Aus irgendeinem Grund gibt Cython 0 für einen mathematischen Ausdruck zurück, der 0,5 ergeben sollte:
print(2 ** (-1)) # prints 0
Seltsamerweise mischen Sie Variablen ein und es wird wie erwartet funktionieren:
i = 1
print(2 ** (-i)) # prints 0.5
Vanilla CPython gibt in beiden Fällen 0,5 zurück. Ich kompiliere für 37m-x86_64-linux-gnu
und bin auf language_level
eingestellt 3
.
Was ist das für eine Hexerei?
python
python-3.x
cython
iTayb
quelle
quelle
language_level
Set auf die Python-Version eingestellt, für die Sie kompilieren? (Die Inkonsistenz ist wahrscheinlich ein Fehler, selbst wenn zwischen Ihrerlanguage_level
und Ihrer Python-Version eineAntworten:
Dies liegt daran, dass C-Ints anstelle von Python-Ganzzahlen verwendet werden, sodass das C-Verhalten eher dem Python-Verhalten entspricht. Ich bin mir relativ sicher, dass dies früher irgendwo als Einschränkung dokumentiert wurde, aber ich kann es jetzt nicht finden. Wenn Sie es als Fehler melden möchten, gehen Sie zu https://github.com/cython/cython/issues , aber ich vermute, dass dies ein bewusster Kompromiss zwischen Geschwindigkeit und Kompatibilität ist.
Der Code wird übersetzt in
wo
__Pyx_pow_long
ist eine Funktion des Typsstatic CYTHON_INLINE long __Pyx_pow_long(long b, long e)
.Der einfachste Weg, dies zu beheben, besteht darin, eine / beide Zahlen in eine Gleitkommazahl zu ändern
Als allgemeiner Kommentar zur Wahl des Designs: Menschen aus der C-Welt erwarten im Allgemeinen
int operator int
sie eine zurückgebenint
, und diese Option wird am schnellsten sein. Python hatte dies in der Vergangenheit mit dem Teilungsverhalten von Python 2 versucht (aber uneinheitlich - die Leistung gab immer eine Gleitkommazahl zurück).Cython versucht im Allgemeinen, dem Verhalten von Python zu folgen. Viele Leute verwenden es jedoch aus Geschwindigkeitsgründen, so dass sie auch versuchen, auf schnelle, C-ähnliche Operationen zurückzugreifen, insbesondere wenn Leute Typen angeben (da diese Leute Geschwindigkeit wollen). Ich denke, was hier passiert ist, ist, dass es möglich war, die Typen automatisch abzuleiten, und daher standardmäßig das C-Verhalten verwendet wurde. Ich vermute, dass es idealerweise zwischen bestimmten Typen und Typen unterscheiden sollte, auf die es geschlossen wird. Es ist jedoch wahrscheinlich auch zu spät, dies zu ändern.
quelle
Es sieht so aus, als würde Cython fälschlicherweise auf den endgültigen Datentyp schließen,
int
anstattfloat
nur Zahlen zu verwendenDer folgende Code funktioniert wie erwartet:
Unter diesem Link finden Sie eine entsprechende Diskussion: https://groups.google.com/forum/#!topic/cython-users/goVpote2ScY
quelle