Vra

Die dokumentasie vir die ronde () funksie bepaal dat jy slaag dit 'n nommer, en die posisie verby die desimale te rond. So dit moet doen dit:

n = 5.59
round(n, 1) # 5.6

Maar, in werklikheid, 'n goeie ou swaai punt vreemd kruip in en jy kry:

5.5999999999999996

Vir die doeleindes van UI, ek moet 5.6 vertoon. Ek steek rondom die Internet en het 'n paar dokumentasie dat hierdie is afhanklik van my implementering van 'n afgestorwene. Ongelukkig, dit gebeur op beide my Windows dev masjien en elke Linux-bediener Ek het probeer. Sien hier ook .

Kort van die skep van my eie ronde biblioteek, is daar geen manier om hierdie?

Was dit nuttig?

Oplossing

Ek kan nie help om die manier waarop dit gestoor, maar ten minste opmaak werk korrek:

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

Ander wenke

opmaak werk korrek selfs sonder om ronde:

"%.1f" % n

As jy die desimale module kan u benader sonder die gebruik van die funksie 'n ronde 'gebruik. Hier is wat ek het al met behulp vir afronding veral tydens die skryf van monetêre aansoeke:

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

Dit sal 'n desimale getal wat is 16,20 terugkeer.

round(5.59, 1) werk boete. Die probleem is dat 5.6 nie voorgestel kan word presies in binêre swaai punt.

>>> 5.6
5.5999999999999996
>>> 

As Vinko sê, jy kan gebruik string opmaak om te doen afronding vir mekaar.

Python het 'n module vir desimale rekenkundige as jy dit nodig het.

Jy kry '5.6 "as jy str(round(n, 1)) in plaas van net round(n, 1).

Jy kan die tipe data oor te skakel na 'n heelgetal:

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

En dan die nommer vertoon deur die invoeging desimaal skeier die land se.

Maar Jimmy se antwoord is beter.

Floating punt wiskunde is kwesbaar vir ligte, maar irriterende, presisie onakkuraathede. As jy kan werk met heelgetal of vaste punt, sal jy gewaarborg presisie.

Neem 'n blik op die Desimale module

  

Desimale "is gebaseer op 'n swaai-punt   model wat ontwerp is met mense   in gedagte, het en noodwendig 'n   kardinale leidende beginsel -   rekenaars moet 'n rekenkundige verskaf   wat werk op dieselfde manier as die   rekenkundige dat mense leer by   skool "-. n uittreksel uit die desimale   rekenkundige spesifikasie.

en

  

Desimale getalle kan voorgestel word   presies. In teenstelling, getalle graag 1.1   en 2.2 nie 'n presiese het   vertoë in binêre swaai   punt. Eindgebruikers tipies sou nie   verwag 1.1 + 2.2 om te vertoon as   3,3000000000000003 as dit die geval is met binêre swaai punt.

Desimale bied die soort operasies wat maak dit maklik om programme wat vereis drywende punt bedrywighede te skryf en ook moet die resultate aan te bied in 'n leesbare formaat, bv rekeningkundige.

Dit is 'n groot probleem inderdaad. Probeer om uit hierdie kode:

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

Dit toon 4.85. Dan doen jy:

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

en dit toon 4.8. Het jy berekeninge met die hand die presiese antwoord is 4,85, maar as jy probeer:

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

Jy kan die waarheid sien:. Die float punt gestoor as die naaste eindige som van breuke waarvan die noemers magte van twee

Jy kan die string formaat operateur %, soortgelyk aan sprintf gebruik.

mystring = "%.2f" % 5.5999

printf die sucker.

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

Werke Perfect

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

Ek doen:

int(round( x , 0))

In hierdie geval, ons eerste ronde behoorlik by die eenheid vlak, dan sit ons met integriteit na vermy druk van 'n float.

so

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

Ek dink hierdie antwoord werk beter as forma die string, en dit maak ook meer sens vir my om die ronde funksie te gebruik.

Kode:

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'

Uitgawe:

5.6
5.7

Hier is waar ek sien ronde gebreke. Wat gebeur as jy wou dié 2 getalle te rond tot een desimale plek? 23,45 23,55 My opvoeding was dat van afronding hierdie jy moet kry: 23.4 23.6 die "reël" is dat jy moet rond as die voorafgaande aantal vreemde was, nie rond as die voorafgaande aantal selfs was. Die ronde funksie in python eenvoudig truncates die 5.

Die probleem is net wanneer laas syfer is 5. Bv. 0,045 intern gestoor as ,044999999999999 ... Jy kan eenvoudig laaste syfer inkrementeer tot 6 en afrond. Dit gee jou die gewenste resultate te gee.

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

Wat van:

round(n,1)+epsilon
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top