2016-01-05 38 views
5

Sono un po 'confuso su come funziona l'arrotondamento in Python.
Qualcuno potrebbe spiegare perché Python si comporta in questo modo?Come funziona Rounding in Python?

Esempio:

>>> round(0.05,1) # this makes sense 
0.1 
>>> round(0.15,1) # this doesn't make sense! Why is the result not 0.2? 
0.1 

e lo stesso per:

>>> round(0.25,1) # this makes sense 
0.3 
>>> round(0.35,1) # in my opinion, should be 0.4 but evaluates to 0.3 
0.3 

Edit: Quindi, in generale, v'è la possibilità che Python arrotonda per difetto, invece di arrotondamento. Quindi devo capire che l'unica cosa "anormale" che può succedere è che Python si arrotonda? O può anche essere arrotondato "in modo anomalo" a causa di come viene memorizzato? (Non ho trovato un caso in cui Python ha arrotondato quando mi aspettavo di arrotondare)

+0

correlati:. 'Print '% .20f% .20f% .20f' % (15, .25, .35) ' –

+0

@Rob_phi: Non correlato: il tuo indice phi viene visualizzato correttamente anche nella visualizzazione degli URL nella barra degli indirizzi [quando faccio clic sul tuo nome utente] ... COME?!? – gariepy

+0

@gariepy Se copi l'URL in un editor di testo verrà visualizzato come 'http: // stackoverflow.com/users/8747/rob% E1% B5% A9' - alcuni browser come Chrome rendono i caratteri unicode sfuggiti in la barra degli URL. – Galax

risposta

12

Questo è in realtà di progettazione. Da Pythons' documentation:

Il comportamento di round() per carri può essere sorprendente: per esempio, dà round(2.675, 2) 2,67 invece dei previsti 2.68. Questo non è un bug: è il risultato del fatto che la maggior parte delle frazioni decimali non può essere rappresentata esattamente come un float.

+1

Beh, questo fa schifo. –

+5

Sì, in particolare "0.15" è internamente rappresentato come '0.1499999999999999944488848768742172978818416595458984375' e" 0.35 "è' 0.34999999999999997779553950749686919152736663818359375'. Entrambe ragionevolmente arrotondate. – Kevin

+0

Quindi, in generale, esiste la possibilità che venga arrotondato per difetto anziché arrotondato per eccesso. Quindi l'unica cosa "anormale" che può accadere è che viene arrotondato per difetto? O può anche essere arrotondato "in modo anomalo" a causa di come viene memorizzato? (Non ho trovato un caso in cui viene arrotondato quando mi aspetto che venga arrotondato per difetto.) –

3

Come esempio, ecco un caso in cui si ottiene arrotondando:

>>> round(0.0499999999999999999,1) 
0.1 

In questo caso, 17 "9" s sono il numero minimo per provocare questo comportamento. Questo perché la rappresentazione interna di 0.0499999999999999999 è 0.05000000000000000277555756156289135105907917022705078125.

7

Sembra a me come è necessario il modulo decimal:

from decimal import * 
x = Decimal('0.15') 
print x.quantize(Decimal('0.1'), rounding=ROUND_HALF_UP) 

uscita:

0.2 
+1

@JonasKaufmann: se hai bisogno di rappresentazioni decimali esatte, come suona come fai tu, questa è la risposta giusta. Inoltre, questo è il motivo per cui Cobol è stato inventato. E. Ancora. In. Uso. :( – gariepy