2010-02-01 23 views
10

Me he encontrado con un problema muy extraño en Python. (El uso de pitón 2.4.x)Problema de redondeo de Python

en Windows:

>>> a = 2292.5 
>>> print '%.0f' % a 
2293 

Pero en Solaris:

>>> a = 2292.5 
>>> print '%.0f' % a 
2292 

Pero este es el mismo en ambos Windows y Solaris:

>>> a = 1.5 
>>> print '%.0f' % a 
2 

¿Alguien puede explicar este comportamiento? Supongo que depende de la plataforma en la forma en que se compiló Python.

+0

Tenga en cuenta que si usted desea conseguir consistentemente la intuitiva redonda" lejos de cero "comportamiento, puede usar la función C99/POSIX.1-2001" roundf ". No estoy seguro de si hay enlaces para eso en Python, o si está disponible en absoluto en Windows; si es importante para usted, podría escribir un módulo C para incluir fácilmente una implementación de terceros. –

Respuesta

10

La función en última instancia, a cargo de la realización de que el formateo es PyOS_snprintf (ver the sources). Según su conjetura, desafortunadamente depende del sistema, es decir, se basa en vsprintf, vsnprintf u otras funciones similares que son finalmente suministradas por la biblioteca C runtime de la plataforma (no recuerdo si el estándar C dice algo sobre '% f' formato para flotadores que están "exactamente a medio camino" entre dos posibles valores redondeados ... pero, si el estándar C es poco estricto al respecto, o mejor dicho, el estándar C es estricto pero algunos tiempos de ejecución de C lo rompen, en última instancia es un problema bastante académico. .).

+3

Creo que algunas implementaciones (de C) redondean cuando el dígito anterior es par y redondeo cuando es impar –

+0

gnibbler - me acabo de volar la cabeza –

+1

@gnibbler, esa es una buena regla contable (incluso mandatorio por ley en algunas jurisdicciones) , Creo), pero luego la contabilidad se realiza invariablemente con números basados ​​en decimales, ** no ** flotantes binarios, por lo que en el contexto de los flotantes esto se convierte en algo discutible ;-). –

0

I depende de la plataforma. Puede encontrar la documentación here.

Es bueno para el usuario ceil o floor cuando sabe lo que quiere (redondear hacia arriba o hacia abajo).

2

round() redondea hacia la más cercana entero par
"% n.nf" funciona de la misma forma como redonda()
int() trunca hacia cero

"redondeo un número positivo al entero más cercano
se puede implementar mediante la adición de 0,5 y truncar"
- http://en.wikipedia.org/wiki/Rounding

En Python se puede hacer esto con: math.trunc(n + 0.5)
suponiendo que n es O positivo f supuesto ...

Donde "media vuelta para incluso" no es apropiado, ahora uso
math.trunc(n + 0.5) donde solía utilizar int(round(n))

+0

En realidad, python no redondea hacia el entero par más cercano: 'si dos múltiplos están igualmente cerca, el redondeo se realiza lejos de 0 (entonces, por ejemplo, round (0.5) es 1.0 y round (-0.5) es -1.0) .' [doc] (http://docs.python.org/2/library/functions.html#round) – ford