Cython печатает неправильные значения чисел больше 65535
Я узнал странное поведение чисел, передаваемых в функцию в Cython со значением, превышающим 65535. Но это появляется только в случае передачи этих чисел в функцию. Если я определю их как
cdef long long a = 145574697
все отлично работает Чтобы прояснить мою проблему, я передаю две фиктивные функции, которые я использовал для исследования этой проблемы
def bigNum1():
cdef long long a = 500000
cdef long long b = 10547746498
cdef long long c = 65536
cdef long long d = 65535
print(a, b, c, d)
def bigNum2(long long a, long long b, long long c, long long d):
print(a, b, c, d)
И "setup.py", который был вызван для получения файла ".pyd".
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("bigNumbers.pyx")
)
После этого я создал файл.pyd с помощью команды
python setup.py build_ext --inplace
используя командную строку. Используемый компилятор c был gcc.
Если я затем вызову либо "bigNum1", либо "bigNum2", получится следующий вывод.
bigNum1: (500000, 10547746498, 65536, 65535)
bigNum2: (41248, 442029762, 0, 65535).
Как видите, все числа больше 65535 отображаются неправильно, используя bigNum2. Вслед за вы видите вызов этой функции.
import bigNumbers
bigNumbers.bigNum1()
a = 500000
b = 10547746498
c = 65536
d = 65535
bigNumbers.bigNum2(a, b, c, d)
Я надеюсь, вы понимаете мою проблему. Я предполагаю, что я сделал неправильное заявление в bigNum2, что приводит к неправильному типу, или мне нужно сделать какой-то тип, прежде чем я передам число этому методу.
РЕДАКТИРОВАТЬ:
Это текст, отображаемый в процессе запроса cmd
python setup.py build_ext --inplace
Compiling bigNumbers.pyx because it changed.
[1/1] Cythonizing bigNumbers.pyx
running build_ext
building 'bigNumbers' extension
D:\WinPython3610\cgg64Bit\bin\gcc.exe -mdll -O -Wall -ID:\WinPython3610\python-3
.6.1.amd64\include -ID:\WinPython3610\python-3.6.1.amd64\include -c bigNumbers.c
-o build\temp.win-amd64-3.6\Release\bignumbers.o
writing build\temp.win-amd64-3.6\Release\bigNumbers.cp36-win_amd64.def
D:\WinPython3610\cgg64Bit\bin\gcc.exe -shared -s build\temp.win-amd64-3.6\Releas
e\bignumbers.o build\temp.win-amd64-3.6\Release\bigNumbers.cp36-win_amd64.def -L
D:\WinPython3610\python-3.6.1.amd64\libs -LD:\WinPython3610\python-3.6.1.amd64\P
Cbuild\amd64 -lpython36 -lvcruntime140 -o L:\User\neon3_worksp
ace\CythonSource\src\bigNumbers.cp36-win_amd64.pyd
EDIT2:
Я использую пакет Winpython "WinPython 3.6.1.0Qt5-64bit", который поставляется с Cython 0.25.2. Но я обновил его с помощью pip, чтобы получить новейшую версию.
Прежде всего, я попытался получить свой.pyd, используя здесь учебник.
http://docs.cython.org/en/latest/src/quickstart/build.html
Но во время сборки я получил сообщение об ошибке "ошибка: невозможно найти vcvarsall.bat". Вот почему я решил использовать Mingw с gcc. Но это также создало ошибку, которая описана в этом посте.
ValueError: Неизвестная версия компилятора MS 1900
И я решил это с ответом Индраджита Канджилала. И вот мы здесь. Я могу создать файл.pyd, могу вызвать функцию, но если значение больше 65535, возникает ошибка. Надеюсь, это поможет.
1 ответ
Короче говоря, не смешивайте компиляторы при компоновке.
Проблема здесь не связана с Cython, но с использованием
- Visual Studio построил дистрибутив Python
- MingW GCC построил расширение Python
и связывая их вместе. Из-за различий в реализации компилятора, в частности, для вышеперечисленных Visual Studio по- разному реализует длинные целые, это будет ломаться разными забавными способами.
При написании расширений Python лучше всегда использовать тот же компилятор, который использовался для распространения Python для сборки расширений.
Для официальных дистрибутивов Python это Visual Studio с 9 по 15 для Py с 2.6 до 3.6 - посмотрите, какой компилятор Microsoft Visual C++ использовать с конкретной версией Python в википедии по Python.
Решением является либо использование Visual Studio 15.0 (также известная как VS 2014, используемая для Python 3.6), либо использование среды conda, которая создает все, включая Python, с GCC.