Python Numpy Arange resultados inesperados

Estoy usando la función arange para definir mis iteraciones de bucle y obtener resultados inesperados.

i = arange(7.8,8.4,0.05) print i 

Usted desarrolla lo siguiente:

 [ 7.8 7.85 7.9 7.95 8. 8.05 8.1 8.15 8.2 8.25 8.3 8.35 8.4 ] 

Sin embargo, utilizando el valor de parada de 8,35 como sigue

 i = arange(7.8,8.35,0.05) 

cede lo siguiente

 [ 7.8 7.85 7.9 7.95 8. 8.05 8.1 8.15 8.2 8.25 8.3 ] 

¡Pero quiero que mi rango termine en 8.35! Sé que puedo usar el valor de parada de> 8.35 y <8.4 para lograr mi resultado, pero ¿por qué es diferente y, en mi opinión, inconsistente?

Edición: estoy usando la versión 2.7

Quizás tenga que ver con limitaciones en los números de punto flotante. Debido a la precisión de la máquina, no es posible almacenar todos los valores concebibles perfectamente como punto flotante. Por ejemplo:

 >>> 8.4 8.4000000000000004 >>> 8.35 8.3499999999999996 

Entonces, 8.4 como punto flotante es ligeramente mayor que el valor real de 8.4, mientras que 8.35 como punto flotante es un poco menos.

Supongo que estás viendo los efectos del redondeo de punto flotante.

numpy.arange hace lo mismo que el range de python: no incluye el “punto final”. (por ejemplo, el range(0, 4, 2) producirá [0,2] lugar de [0,2,4] )

Sin embargo, para los pasos de punto flotante, los errores de redondeo se acumulan y, en ocasiones, el último valor incluirá realmente el punto final.

Como se indica en la documentación de arange :

Cuando se usa un paso no entero, como 0.1, los resultados a menudo no serán consistentes. Es mejor usar linspace para estos casos.

numpy.linspace genera un número específico de puntos entre un punto inicial y uno final. Por cierto, incluye los puntos finales de forma predeterminada.

la ayuda de la función arange dice

  For floating point arguments, the length of the result is ``ceil((stop - start)/step)``. Because of floating point overflow, this rule may result in the last element of `out` being greater than `stop`. 

para Python 2.7, las conversiones entre números de punto flotante y cadenas ahora se redondean correctamente en la mayoría de las plataformas.

en 2.7

 >>> float(repr(2.3)) 2.3 

en 2.6

 >>> float(repr(2.3)) 2.2999999999999998 

Tuve el mismo problema e implementé mi propia función para corregir este problema de redondeo con numpy.arange:

 import numpy as np def my_arange(a, b, dr, decimals=6): res = [a] k = 1 while res[-1] < b: tmp = round(a + k*dr,decimals) if tmp > b: break res.append(tmp) k+=1 return np.asarray(res)