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, но с использованием

  1. Visual Studio построил дистрибутив Python
  2. 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.

Другие вопросы по тегам