Ik wil dat a
wordt afgerond op 13,95.
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
De functie round
werkt niet werken zoals ik had verwacht.
Antwoord 1, autoriteit 100%
Je loopt tegen het oude probleem aan met getallen met drijvende komma dat niet alle getallen kunnen worden weergegeven precies. De opdrachtregel toont u alleen de volledige drijvende-kommavorm uit het geheugen.
Bij drijvende-kommaweergave is uw afgeronde versie hetzelfde getal. Aangezien computers binair zijn, slaan ze getallen met drijvende komma op als een geheel getal en delen ze vervolgens door een macht van twee, zodat 13,95 op dezelfde manier wordt weergegeven als 125650429603636838/(2**53).
Getallen met dubbele precisie hebben een nauwkeurigheid van 53 bits (16 cijfers) en gewone floats hebben een nauwkeurigheid van 24 bits (8 cijfers). Het floating point type in Python gebruikt dubbele precisie om de waarden op te slaan.
Bijvoorbeeld
>>> 125650429603636838/(2**53)
13.949999999999999
>>> 234042163/(2**24)
13.949999988079071
>>> a = 13.946
>>> print(a)
13.946
>>> print("%.2f" % a)
13.95
>>> round(a,2)
13.949999999999999
>>> print("%.2f" % round(a, 2))
13.95
>>> print("{:.2f}".format(a))
13.95
>>> print("{:.2f}".format(round(a, 2)))
13.95
>>> print("{:.15f}".format(round(a, 2)))
13.949999999999999
Als je na slechts twee decimalen komt (om bijvoorbeeld een valutawaarde weer te geven), dan heb je een paar betere keuzes:
- Gebruik gehele getallen en sla waarden op in centen, niet in dollars, en deel deze vervolgens door 100 om te converteren naar dollars.
- Of gebruik een vast puntgetal, zoals decimaal.
Antwoord 2, autoriteit 35%
Er zijn nieuwe formaatspecificaties, Stringformaatspecificatie Minitaal:
Je kunt hetzelfde doen als:
"{:.2f}".format(13.949999999999999)
Opmerking 1: het bovenstaande retourneert een tekenreeks. Om als float te krijgen, wikkel je eenvoudig met float(...)
:
float("{:.2f}".format(13.949999999999999))
Opmerking 2: inpakken met float()
verandert niets:
>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True
Antwoord 3, autoriteit 18%
De ingebouwde round()
werkt prima in Python 2.7 of hoger.
Voorbeeld:
>>> round(14.22222223, 2)
14.22
Bekijk de documentatie.
Antwoord 4, autoriteit 8%
Ik denk dat de eenvoudigste aanpak is om de functie format()
te gebruiken.
Bijvoorbeeld:
a = 13.949999999999999
format(a, '.2f')
13.95
Dit levert een zwevend getal op als een tekenreeks die is afgerond op twee decimalen.
Antwoord 5, autoriteit 7%
Niemand hier lijkt het nog te hebben genoemd, dus laat me een voorbeeld geven in het f-string/template-string-formaat van Python 3.6, wat ik mooi netjes vind:
>>> f'{a:.2f}'
Het werkt ook goed met langere voorbeelden, met operators en zonder haakjes:
>>> print(f'Completed in {time.time() - start:.2f}s')
Antwoord 6, autoriteit 5%
De meeste getallen kunnen niet exact worden weergegeven in floats. Als u het getal wilt afronden omdat dat is wat uw wiskundige formule of algoritme vereist, dan wilt u rond gebruiken. Als je de weergave alleen tot een bepaalde precisie wilt beperken, gebruik dan niet eens rond en formatteer het gewoon als die string. (Als je het wilt weergeven met een alternatieve afrondingsmethode, en er zijn tonnen, dan moet je de twee benaderingen mengen.)
>>> "%.2f" % 3.14159
'3.14'
>>> "%.2f" % 13.9499999
'13.95'
En als laatste, hoewel misschien wel het belangrijkste, als je exacte wiskunde wilt, dan wil je helemaal geen floats. Het gebruikelijke voorbeeld is omgaan met geld en het opslaan van ‘centen’ als een geheel getal.
Antwoord 7, autoriteit 5%
Gebruik
print"{:.2f}".format(a)
in plaats van
print"{0:.2f}".format(a)
Omdat dit laatste kan leiden tot uitvoerfouten bij het uitvoeren van meerdere variabelen (zie opmerkingen).
Antwoord 8, autoriteit 3%
Probeer de onderstaande code:
>>> a = 0.99334
>>> a = int((a * 100) + 0.5) / 100.0 # Adding 0.5 rounds it up
>>> print a
0.99
Antwoord 9, autoriteit 3%
TLDR 😉
Het afrondingsprobleem van invoer/uitvoer is definitief opgelost door Python 2.7.0 en 3.1.
Een correct afgerond getal kan omkeerbaar heen en weer worden geconverteerd:
str -> float() -> repr() -> float() ...
of Decimal -> float -> str -> Decimal
Een decimale type is niet meer nodig voor opslag.
(Natuurlijk kan het nodig zijn om een resultaat van het optellen of aftrekken van afgeronde getallen af te ronden om de geaccumuleerde laatste bit-fouten te elimineren. Een expliciete decimale rekenkunde kan nog steeds handig zijn, maar een conversie naar string door str()
(dat wil zeggen met afronding op 12 geldige cijfers) is meestal goed genoeg als er geen extreme nauwkeurigheid of geen extreem aantal opeenvolgende rekenkundige bewerkingen vereist is.)
Oneindige test:
import random
from decimal import Decimal
for x in iter(random.random, None): # Verify FOREVER that rounding is fixed :-)
assert float(repr(x)) == x # Reversible repr() conversion.
assert float(Decimal(repr(x))) == x
assert len(repr(round(x, 10))) <= 12 # Smart decimal places in repr() after round.
if x >= 0.1: # Implicit rounding to 12 significant digits
assert str(x) == repr(round(x, 12)) # by str() is good enough for small errors.
y = 1000 * x # Decimal type is excessive for shopping
assert str(y) == repr(round(y, 12 - 3)) # in a supermaket with Python 2.7+ :-)
Documentatie
Zie de Release-opmerkingen Python 2.7 – Andere taalwijzigingen de vierde alinea:
Conversies tussen getallen met drijvende komma en tekenreeksen worden nu op de meeste platforms correct afgerond. Deze conversies komen op veel verschillende plaatsen voor: str() op floats en complexe getallen; de float en complexe constructeurs; numerieke opmaak; het serialiseren en de-serialiseren van floats en complexe getallen met behulp van de modules
marshal
,pickle
enjson
; ontleden van float en denkbeeldige literals in Python-code; en decimaal-naar-zwevend conversie.Hieraan gerelateerd, retourneert de repr() van een getal met drijvende komma x nu een resultaat op basis van de kortste decimale tekenreeks die gegarandeerd terug naar x wordt afgerond onder de juiste afronding (met afrondingsmodus rond-half-naar-even). Voorheen gaf het een string op basis van het afronden van x op 17 decimale cijfers.
Meer informatie: De opmaak van float
vóór Python 2.7 was vergelijkbaar met de huidige numpy.float64
. Beide typen gebruiken dezelfde 64-bits IEEE 754 dubbele precisie met 52-bits mantisse. Een groot verschil is dat np.float64.__repr__
vaak wordt geformatteerd met een buitensporig decimaal getal zodat er geen bit verloren kan gaan, maar er bestaat geen geldig IEEE 754-nummer tussen 13.94999999999999 en 13.950000000000001. Het resultaat is niet mooi en de conversie repr(float(number_as_string))
is niet omkeerbaar met numpy. Aan de andere kant: float.__repr__
is zo opgemaakt dat elk cijfer belangrijk is; de volgorde is zonder gaten en de conversie is omkeerbaar. Simpel: als je misschien een numpy.float64-nummer hebt, converteer het dan naar normaal float om te worden geformatteerd voor mensen, niet voor numerieke processors, anders is er niets meer nodig met Python 2.7+.
Antwoord 10, autoriteit 3%
U kunt het uitvoerformaat wijzigen:
>>> a = 13.95
>>> a
13.949999999999999
>>> print "%.2f" % a
13.95
Antwoord 11, autoriteit 3%
Met Python < 3 (bijv. 2.6 of 2.7), zijn er twee manieren om dit te doen.
# Option one
older_method_string = "%.9f" % numvar
# Option two (note ':' before the '.9f')
newer_method_string = "{:.9f}".format(numvar)
Maar houd er rekening mee dat voor Python-versies boven 3 (bijv. 3.2 of 3.3), optie twee voorkeur.
Voor meer informatie over optie twee raad ik deze link aan over stringopmaak van de Python-documentatie.
En voor meer informatie over optie één, deze link is voldoende en heeft informatie over de verschillende vlaggen.
Referentie: drijvend converteren verwijs nummer naar een bepaalde precisie en kopieer vervolgens naar string
Antwoord 12, autoriteit 2%
U kunt de operator format gebruiken om de waarde in python tot op 2 decimalen af te ronden:
print(format(14.4499923, '.2f')) // output is 14.45
Antwoord 13, autoriteit 2%
float_number = 12.234325335563
round(float_number, 2)
Dit komt terug;
12.23
Uitleg:
afrondfunctie heeft twee argumenten;
Getal dat moet worden afgerond en het aantal decimalen dat moet worden geretourneerd. Hier heb ik 2 decimalen geretourneerd.
Antwoord 14, autoriteit 2%
In Python 2.7:
a = 13.949999999999999
output = float("%0.2f"%a)
print output
Antwoord 15
Zoals @Matt opmerkte, Python 3.6 biedt f-strings, en ze kunnen ook geneste parameters:
value = 2.34558
precision = 2
width = 4
print(f'result: {value:{width}.{precision}f}')
die result: 2.35
Antwoord 16
De Python-tutorial heeft een appendix genaamd Floating Point Rekenkunde: problemen en beperkingen. Lees het. Het legt uit wat er gebeurt en waarom Python zijn best doet. Het heeft zelfs een voorbeeld dat overeenkomt met het uwe. Laat me een beetje citeren:
>>> 0.1 0.10000000000000001
je komt misschien in de verleiding om de
round()
. te gebruiken
functie om het terug te hakken naar de single
cijfer dat u verwacht. Maar dat maakt niet uit
verschil:>>> round(0.1, 1) 0.10000000000000001
Het probleem is dat het binaire
drijvende-kommawaarde opgeslagen voor“0.1”
was al de best mogelijke binaire
benadering tot1/10
, dus probeer
er nog een keer omheen kan het niet beter maken:
het was al zo goed als maar kan.Een ander gevolg is dat sinds
0.1
is niet precies1/10
, tien optellend
waarden van0.1
leveren mogelijk niet precies op
1.0
, ofwel:>>> sum = 0.0 >>> for i in range(10): ... sum += 0.1 ... >>> sum 0.99999999999999989
Een alternatief en oplossing voor uw problemen is het gebruik van de decimal
-module.
Antwoord 17
We hebben meerdere opties om dat te doen:
Optie 1:
x = 1.090675765757
g = float("{:.2f}".format(x))
print(g)
Optie 2:
De ingebouwde round() ondersteunt Python 2.7 of hoger.
x = 1.090675765757
g = round(x, 2)
print(g)
Antwoord 18
Gebruik een combinatie van Decimaal object en round() methode.
Python 3.7.3
>>> from decimal import Decimal
>>> d1 = Decimal (13.949999999999999) # define a Decimal
>>> d1
Decimal('13.949999999999999289457264239899814128875732421875')
>>> d2 = round(d1, 2) # round to 2 decimals
>>> d2
Decimal('13.95')
Antwoord 19
Het doet precies wat je het zei te doen en werkt correct. Lees meer over floating point-verwarring en probeer misschien decimale objecten in plaats daarvan.
Antwoord 20
from decimal import Decimal
def round_float(v, ndigits=2, rt_str=False):
d = Decimal(v)
v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits))
if rt_str:
return v_str
return Decimal(v_str)
Resultaten:
Python 3.6.1 (default, Dec 11 2018, 17:41:10)
>>> round_float(3.1415926)
Decimal('3.14')
>>> round_float(3.1445926)
Decimal('3.14')
>>> round_float(3.1455926)
Decimal('3.15')
>>> round_float(3.1455926, rt_str=True)
'3.15'
>>> str(round_float(3.1455926))
'3.15'
Antwoord 21
Voor het corrigeren van de drijvende komma in typedynamische talen zoals Python en JavaScript, gebruik ik deze techniek
# For example:
a = 70000
b = 0.14
c = a * b
print c # Prints 980.0000000002
# Try to fix
c = int(c * 10000)/100000
print c # Prints 980
U kunt decimaal ook als volgt gebruiken:
from decimal import *
getcontext().prec = 6
Decimal(1) / Decimal(7)
# Results in 6 precision -> Decimal('0.142857')
getcontext().prec = 28
Decimal(1) / Decimal(7)
# Results in 28 precision -> Decimal('0.1428571428571428571428571429')
Antwoord 22
Hoe zit het met een lambda-functie zoals deze:
arred = lambda x,n : x*(10**n)//1/(10**n)
Op deze manier zou je gewoon kunnen doen:
arred(3.141591657,2)
en krijg
3.14
Antwoord 23
orig_float = 232569 / 16000.0
14.5355625
short_float = float("{:.2f}".format(orig_float))
14.54
Antwoord 24
Het is simpel, zoals 1,2,3:
-
gebruik decimaal module voor snelle correct afgeronde decimale drijvende komma rekenkunde:
d=Decimaal (10000000.0000009)
om afronding te bereiken:
d.quantize(Decimal('0.01'))
resultaten met Decimal('10000000.00')
- maak hierboven DRY:
def round_decimal(number, exponent='0.01'):
decimal_value = Decimal(number)
return decimal_value.quantize(Decimal(exponent))
OF
def round_decimal(number, decimal_places=2):
decimal_value = Decimal(number)
return decimal_value.quantize(Decimal(10) ** -decimal_places)
- upvote dit antwoord 🙂
PS: kritiek van anderen: opmaak is niet afronden.
Antwoord 25
Om een getal naar een resolutie af te ronden, is de beste manier de volgende, die met elke resolutie kan werken (0,01 voor twee decimalen of zelfs andere stappen):
>>> import numpy as np
>>> value = 13.949999999999999
>>> resolution = 0.01
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
13.95
>>> resolution = 0.5
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
14.0
Antwoord 26
De antwoorden die ik zag werkten niet met het geval float (52.15). Na wat testen is er de oplossing die ik gebruik:
import decimal
def value_to_decimal(value, decimal_places):
decimal.getcontext().rounding = decimal.ROUND_HALF_UP # define rounding method
return decimal.Decimal(str(float(value))).quantize(decimal.Decimal('1e-{}'.format(decimal_places)))
(De conversie van de ‘waarde’ naar float en dan string is erg belangrijk, op die manier kan ‘value’ van het type float, decimaal, integer of string zijn!)
Ik hoop dat dit iemand helpt.
Antwoord 27
lambda x,n:int(x*10n+.5)/10n heeft vele jaren voor mij gewerkt in vele talen.
Antwoord 28
Als je met geld wilt omgaan, gebruik dan de python decimaal-module
from decimal import Decimal, ROUND_HALF_UP
# amount can be integer, string, tuple, float, or another Decimal object
def to_money(amount) -> Decimal:
money = Decimal(amount).quantize(Decimal('.00'), rounding=ROUND_HALF_UP)
return money
Antwoord 29
Hier is de eenvoudige oplossing met de formaatfunctie.
float(format(num, '.2f'))
OPMERKING: we converteren getallen naar zwevend omdat de formaatmethode is
terugkerende tekenreeks.
Antwoord 30
De methode die ik gebruik is die van string slicing. Het is relatief snel en eenvoudig.
Converteer eerst de float naar een string en kies vervolgens de lengte die je wilt hebben.
float = str(float)[:5]
In de enkele regel hierboven hebben we de waarde geconverteerd naar een tekenreeks en vervolgens de tekenreeks behouden tot de eerste vier cijfers of tekens (inclusief).
Hopelijk helpt dat!