Por alguna razón, Cython devuelve 0 en una expresión matemática que debería evaluar a 0.5:
print(2 ** (-1)) # prints 0
Por extraño que parezca, mezcle las variables y funcionará como se esperaba:
i = 1
print(2 ** (-i)) # prints 0.5
Vanilla CPython devuelve 0.5 para ambos casos. Estoy compilando 37m-x86_64-linux-gnu
y language_level
está configurado para 3
.
¿Qué es esta brujería?
python
python-3.x
cython
iTayb
fuente
fuente
language_level
configurado para la versión de Python para la que está compilando? (La inconsistencia es probablemente un error, incluso si tiene un desajuste entre sulanguage_level
y su versión de Python, pero esta información es importante para diagnosticar el problema.)Respuestas:
Se debe a que está usando entradas C en lugar de números enteros de Python, por lo que coincide con el comportamiento de C en lugar del comportamiento de Python. Estoy relativamente seguro de que esto solía documentarse como una limitación en alguna parte, pero ahora no puedo encontrarlo. Si desea informarlo como un error, vaya a https://github.com/cython/cython/issues , pero sospecho que esto es una compensación deliberada de velocidad por compatibilidad.
El código se traduce a
donde
__Pyx_pow_long
es una función del tipostatic CYTHON_INLINE long __Pyx_pow_long(long b, long e)
.La forma más fácil de solucionarlo es cambiar uno / ambos números para que sean un número de coma flotante
Como comentario general sobre la elección del diseño: las personas del mundo C generalmente esperan
int operator int
regresar unint
, y esta opción será más rápida. Python había intentado hacer esto en el pasado con el comportamiento de división de Python 2 (pero inconsistentemente, la potencia siempre devolvía un número de coma flotante).Cython generalmente intenta seguir el comportamiento de Python. Sin embargo, muchas personas lo usan para la velocidad, por lo que también intentan recurrir a operaciones rápidas, similares a C, especialmente cuando las personas especifican tipos (ya que esas personas quieren velocidad). Creo que lo que sucedió aquí es que ha sido capaz de inferir los tipos automáticamente y, por lo tanto, el comportamiento predeterminado es C. Sospecho que idealmente debería distinguir entre tipos específicos y tipos que se infiere. Sin embargo, probablemente también sea demasiado tarde para comenzar a cambiar eso.
fuente
Parece que Cython infiere incorrectamente el tipo de datos final en
int
lugar defloat
cuando solo están involucrados númerosEl siguiente código funciona como se esperaba:
Vea este enlace para una discusión relacionada: https://groups.google.com/forum/#!topic/cython-users/goVpote2ScY
fuente