Frage

Die Dokumentation für die round() Funktion besagt, dass es eine Zahl ist, und die Positionen der Vergangenheit der Dezimalstelle zu Runden.So ist es sollte tun Sie dies:

n = 5.59
round(n, 1) # 5.6

Aber in Wirklichkeit, die gute alte floating point Seltsamkeit schleicht und Sie erhalten:

5.5999999999999996

Für die Zwecke der UI, I need to display 5.6.Ich stocherte im Internet und fand einige Dokumentation dass dies abhängig ist meine Implementierung von Python.Leider, dies geschieht sowohl auf meinem Windows-dev-Maschine, und jede Linux-server die ich ausprobiert habe. Siehe auch hier.

Kurz meine eigene Bibliothek Runde, gibt es eine Möglichkeit, um dieses?

War es hilfreich?

Lösung

Ich kann die Art und Weise nicht helfen, es ist gespeichert, aber zumindest die Formatierung korrekt funktioniert:

'%.1f' % round(n, 1) # Gives you '5.6'

Andere Tipps

Die Formatierung korrekt funktioniert auch ohne zu Runde mit:

"%.1f" % n

Wenn Sie das Dezimal-Modul, das Sie ohne die Verwendung der ‚runden‘ Funktion annähern können. Hier ist, was ich für die Rundung insbesondere unter Verwendung von beim Schreiben Geld Anwendungen:

Decimal(str(16.2)).quantize(Decimal('.01'), rounding=ROUND_UP)

Dies wird eine Dezimalzahl zurück, die 16.20 ist.

round(5.59, 1) funktioniert gut. Das Problem ist, dass 5.6 kann nicht genau in Punkt binärer Fließ dargestellt werden.

>>> 5.6
5.5999999999999996
>>> 

Wie Vinko sagt, können Sie String-Formatierung für die Anzeige zu tun Runden.

Python hat einen Modul für Dezimalarithmetik , wenn Sie das brauchen.

Sie erhalten '5.6', wenn Sie statt nur str(round(n, 1)) do round(n, 1).

Sie können den Datentyp auf eine ganze Zahl wechseln:

>>> n = 5.59
>>> int(n * 10) / 10.0
5.5
>>> int(n * 10 + 0.5)
56

Und dann die Nummer angezeigt wird durch das Gebietsschema des Dezimaltrennzeichens eingefügt wird.

Allerdings Jimmys Antwort ist besser.

Gleitkomma-Mathematik ist anfällig für leichte, aber ärgerlich, Präzision Ungenauigkeiten. Wenn Sie mit Integer- oder festen Punkt arbeiten können, werden Sie garantiert Präzision werden.

Werfen Sie einen Blick auf die Dezimal-Modul

  

Dezimal „basiert auf einem Fließkomma   Modell, das mit Menschen entworfen wurde,   im Auge, und notwendigerweise ein   von größter Bedeutung Leitprinzip -   Computer müssen eine arithmetische liefern   das funktioniert in der gleichen Weise wie die   Arithmetik, dass die Menschen lernen,   Schule.“- Auszug aus dem Dezimalsystem   Arithmetik-Spezifikation.

und

  

Dezimalzahlen können dargestellt werden   genau. Im Gegensatz dazu mögen Zahlen 1.1   und 2.2 haben keine genaue   Darstellungen in binären Fließ   Punkt. Endanwender würden typischerweise nicht   erwarten 1.1 + 2.2 angezeigt werden als   3,3000000000000003 wie es binäre Gleitkomma tut mit.

Dezimal bietet die Art von Operationen, die es einfach machen, Anwendungen zu schreiben, die Floating-Point-Operationen erfordern und auch muß diese Ergebnisse in einem für Menschen lesbares Format präsentieren, zum Beispiel Buchhaltung.

Es ist ein großes Problem in der Tat. Probieren Sie diesen Code ein:

print "%.2f" % (round((2*4.4+3*5.6+3*4.4)/8,2),)

Es zeigt 4,85. Dann sind Sie tun:

print "Media = %.1f" % (round((2*4.4+3*5.6+3*4.4)/8,1),)

, und es zeigt 4.8. Haben Sie Berechnungen von Hand die genaue Antwort ist 4,85, aber wenn Sie versuchen:

print "Media = %.20f" % (round((2*4.4+3*5.6+3*4.4)/8,20),)

Sie, die Wahrheit sehen. Der Schwimmer Punkt als nächste endliche Summe von Fraktionen, deren Nenner sind Zweierpotenzen gespeichert

Sie können die String-Format Operator %, ähnlich wie sprintf verwenden.

mystring = "%.2f" % 5.5999

printf der Sauger.

print '%.1f' % 5.59  # returns 5.6

funktioniert perfekt

format(5.59, '.1f') # to display
float(format(5.59, '.1f')) #to round

ich tue:

int(round( x , 0))

In diesem Fall haben wir erste Runde richtig auf die Einheit, dann wandeln wir integer Drucken eines Schwimmers zu vermeiden.

so

>>> int(round(5.59,0))
6

Ich glaube, diese Antwort funktioniert besser als die Zeichenfolge Formatierung, und es macht auch mehr sens mir die Rundenfunktion zu verwenden.

Code:

x1 = 5.63
x2 = 5.65
print(float('%.2f' % round(x1,1)))  # gives you '5.6'
print(float('%.2f' % round(x2,1)))  # gives you '5.7'

Ausgabe:

5.6
5.7

Hier sehe ich, dass die Runde versagt.Was wäre, wenn Sie diese beiden Zahlen auf eine Dezimalstelle runden möchten?23.45 23.55 Meine Ausbildung war, dass Sie durch die Abrunden von diesen erhalten sollten:23.4 23.6 Die "Regel" ist, dass Sie sich zusammenschließen sollten, wenn die vorhergehende Zahl ungerade war, nicht runden, wenn die vorhergehende Zahl gleichmäßig war.Die Round-Funktion in Python schneidet einfach die 5 ab.

Das Problem ist nur, wenn letzte Ziffer 5. Eg. 0.045 wird intern als ,044999999999999 gespeichert ... Sie einfach letzte Ziffer 6 und abrunden erhöhen könnte. Dies gibt Ihnen die gewünschten Ergebnisse.

import re


def custom_round(num, precision=0):
    # Get the type of given number
    type_num = type(num)
    # If the given type is not a valid number type, raise TypeError
    if type_num not in [int, float, Decimal]:
        raise TypeError("type {} doesn't define __round__ method".format(type_num.__name__))
    # If passed number is int, there is no rounding off.
    if type_num == int:
        return num
    # Convert number to string.
    str_num = str(num).lower()
    # We will remove negative context from the number and add it back in the end
    negative_number = False
    if num < 0:
        negative_number = True
        str_num = str_num[1:]
    # If number is in format 1e-12 or 2e+13, we have to convert it to
    # to a string in standard decimal notation.
    if 'e-' in str_num:
        # For 1.23e-7, e_power = 7
        e_power = int(re.findall('e-[0-9]+', str_num)[0][2:])
        # For 1.23e-7, number = 123
        number = ''.join(str_num.split('e-')[0].split('.'))
        zeros = ''
        # Number of zeros = e_power - 1 = 6
        for i in range(e_power - 1):
            zeros = zeros + '0'
        # Scientific notation 1.23e-7 in regular decimal = 0.000000123
        str_num = '0.' + zeros + number
    if 'e+' in str_num:
        # For 1.23e+7, e_power = 7
        e_power = int(re.findall('e\+[0-9]+', str_num)[0][2:])
        # For 1.23e+7, number_characteristic = 1
        # characteristic is number left of decimal point.
        number_characteristic = str_num.split('e+')[0].split('.')[0]
        # For 1.23e+7, number_mantissa = 23
        # mantissa is number right of decimal point.
        number_mantissa = str_num.split('e+')[0].split('.')[1]
        # For 1.23e+7, number = 123
        number = number_characteristic + number_mantissa
        zeros = ''
        # Eg: for this condition = 1.23e+7
        if e_power >= len(number_mantissa):
            # Number of zeros = e_power - mantissa length = 5
            for i in range(e_power - len(number_mantissa)):
                zeros = zeros + '0'
            # Scientific notation 1.23e+7 in regular decimal = 12300000.0
            str_num = number + zeros + '.0'
        # Eg: for this condition = 1.23e+1
        if e_power < len(number_mantissa):
            # In this case, we only need to shift the decimal e_power digits to the right
            # So we just copy the digits from mantissa to characteristic and then remove
            # them from mantissa.
            for i in range(e_power):
                number_characteristic = number_characteristic + number_mantissa[i]
            number_mantissa = number_mantissa[i:]
            # Scientific notation 1.23e+1 in regular decimal = 12.3
            str_num = number_characteristic + '.' + number_mantissa
    # characteristic is number left of decimal point.
    characteristic_part = str_num.split('.')[0]
    # mantissa is number right of decimal point.
    mantissa_part = str_num.split('.')[1]
    # If number is supposed to be rounded to whole number,
    # check first decimal digit. If more than 5, return
    # characteristic + 1 else return characteristic
    if precision == 0:
        if mantissa_part and int(mantissa_part[0]) >= 5:
            return type_num(int(characteristic_part) + 1)
        return type_num(characteristic_part)
    # Get the precision of the given number.
    num_precision = len(mantissa_part)
    # Rounding off is done only if number precision is
    # greater than requested precision
    if num_precision <= precision:
        return num
    # Replace the last '5' with 6 so that rounding off returns desired results
    if str_num[-1] == '5':
        str_num = re.sub('5$', '6', str_num)
    result = round(type_num(str_num), precision)
    # If the number was negative, add negative context back
    if negative_number:
        result = result * -1
    return result

Was ist mit:

round(n,1)+epsilon
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top