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-gnuy language_levelestá configurado para 3.
¿Qué es esta brujería?
python
python-3.x
cython
iTayb
fuente
fuente

language_levelconfigurado para la versión de Python para la que está compilando? (La inconsistencia es probablemente un error, incluso si tiene un desajuste entre sulanguage_levely 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_longes 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 intregresar 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
intlugar defloatcuando 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