cython 打印大于 65535 的数字的错误值
cython prints wrong values of numbers bigger than 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)
以及被调用以获取“.pyd”文件的 "setup.py"。
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
编辑2:
我使用 cython 0.25.2 附带的 Winpython 包 "WinPython 3.6.1.0Qt5-64bit"。但是我用pip升级了它以获得最新版本。
首先,我尝试使用此处的教程获取我的 .pyd。
http://docs.cython.org/en/latest/src/quickstart/build.html
但是在构建过程中我收到一条错误消息 "error: Unable to find vcvarsall.bat"。这就是为什么我决定将 Mingw 与 gcc 一起使用。但这也产生了一个错误,在 post.
上有描述
ValueError: Unknown MS Compiler version 1900
我用 Indrajit Kanjilal 的回答解决了这个问题。我们现在就在那里。我可以创建一个 .pyd 文件,可以调用该函数,但如果值大于 65535,则会发生错误。希望有所帮助。
简而言之,链接时不要混用编译器。
这里的问题与 Cython 无关,但与使用有关
- Visual Studio 内置 Python 分布
- MingW GCC 内置 Python 扩展
并将它们链接在一起。由于编译器实现差异,特别是对于上述 Visual Studio 实现 long ints 不同,这将以各种有趣的方式中断。
编写 Python 扩展时,最好始终使用与 Python 发行版相同的编译器来构建扩展。
对于官方 Python 发行版,对于 Py 2.6 到 3.6,这些是 Visual Studio 9 到 15 - 参见 Which Microsoft Visual C++ compiler to use with a specific Python version on the Python wiki。
解决方案是使用 Visual Studio 15.0(又名 VS 2014,用于 Python 3.6),或者使用 conda 环境构建所有内容,包括 Python使用 GCC。
我发现在 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)
以及被调用以获取“.pyd”文件的 "setup.py"。
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
编辑2:
我使用 cython 0.25.2 附带的 Winpython 包 "WinPython 3.6.1.0Qt5-64bit"。但是我用pip升级了它以获得最新版本。
首先,我尝试使用此处的教程获取我的 .pyd。
http://docs.cython.org/en/latest/src/quickstart/build.html
但是在构建过程中我收到一条错误消息 "error: Unable to find vcvarsall.bat"。这就是为什么我决定将 Mingw 与 gcc 一起使用。但这也产生了一个错误,在 post.
上有描述ValueError: Unknown MS Compiler version 1900
我用 Indrajit Kanjilal 的回答解决了这个问题。我们现在就在那里。我可以创建一个 .pyd 文件,可以调用该函数,但如果值大于 65535,则会发生错误。希望有所帮助。
简而言之,链接时不要混用编译器。
这里的问题与 Cython 无关,但与使用有关
- Visual Studio 内置 Python 分布
- MingW GCC 内置 Python 扩展
并将它们链接在一起。由于编译器实现差异,特别是对于上述 Visual Studio 实现 long ints 不同,这将以各种有趣的方式中断。
编写 Python 扩展时,最好始终使用与 Python 发行版相同的编译器来构建扩展。
对于官方 Python 发行版,对于 Py 2.6 到 3.6,这些是 Visual Studio 9 到 15 - 参见 Which Microsoft Visual C++ compiler to use with a specific Python version on the Python wiki。
解决方案是使用 Visual Studio 15.0(又名 VS 2014,用于 Python 3.6),或者使用 conda 环境构建所有内容,包括 Python使用 GCC。