2011-03-01 21 views
5

Pido disculpas por la pregunta realmente simple y tonta; sin embargo, ¿por qué hay una diferencia en la precisión mostrada para estos dos casos?Precisión del punto flotante en la matriz Python

1)

>> test = numpy.array([0.22]) 
>> test2 = test[0] * 2 
>> test2 
0.44 

2)

>> test = numpy.array([0.24]) 
>> test2 = test[0] * 2 
>> test2 
0.47999999999999998 

estoy usando python2.6.6 en Linux de 64 bits. Gracias de antemano por su ayuda.

Esto también contener parece ser el caso para una lista en Python

>>> t = [0.22] 
>>> t 
[0.22] 

>>> t = [0.24] 
>>> t 
[0.23999999999999999] 
+2

Eso es como flotadores de trabajo - "de manera misteriosa";). Dupe de tantas preguntas que no puedo conformarme con una. – delnan

+1

No llamaría a esto un duplicado de nada, ya que la respuesta es muy específica para Python (además es mi respuesta :)). – Zooba

Respuesta

6

porque son diferentes números y números diferentes tienen diferentes efectos de redondeo.

(Prácticamente ninguna de las preguntas relacionadas abajo del lado derecho explicará la causa de los propios efectos de redondeo.)


Bien respuesta, más grave. Parece que numpy realiza alguna transformación o el cálculo de los números en una matriz:

>>> t = numpy.array([0.22]) 
>>> t[0] 
0.22 


>>> t = numpy.array([0.24]) 
>>> t[0] 
0.23999999999999999 

mientras que Python no hace esto automáticamente:

>>> t = 0.22 
>>> t 
0.22 

>>> t = 0.24 
>>> t 
0.24 

El error de redondeo es menor que numpy de "eps" valor para float, lo que implica que debe ser tratada como igual (y de hecho lo es):

>>> abs(numpy.array([0.24])[0] - 0.24) < numpy.finfo(float).eps 
True 

>>> numpy.array([0.24])[0] == 0.24 
True 

Pero la razón de que Python lo muestra como '0,24' y nu mpa no lo hace es porque método por defecto de Python usa float.__repr__ menor precisión (que, IIRC, fue un cambio bastante reciente):

>>> str(numpy.array([0.24])[0]) 
0.24 

>>> '%0.17f' % 0.24 
'0.23999999999999999' 
+0

Extraño ... Las carrozas de Python son dobles de C, sin embargo, no debería haber ninguna diferencia. A menos que NumPy use una sola precisión (flotantes C) por alguna razón extraña. – delnan

+1

Incluso sin Numpy, parece que Python hace lo mismo si el valor está en una lista '>>> t = [0.22]' '>>> t' '[0.22]' '>>> t = [0.24]' '>>> t' '[0.239999999]' – Eric

+2

@Eric No vi ese efecto cuando lo intenté, pero la respuesta es que 'numpy.float64 .__ repr__' usa una gran precisión en' '% 0. # f'' que el 'float .__ repr__' de Python. (Que ahora está en mi respuesta.) – Zooba

Cuestiones relacionadas