是否有可能以某种方式覆盖或重载 python 中整数/数字的标准实现,以便它像 32 位整数一样工作。
a: int
a = 4076863488
>>> -218103808
或者是否有可能以某种方式定义一个不能改变类型的变量?做类似的事情:x: int
?
我想这样做是因为在每个位操作和赋值上编写 ctypes.c_int32(n)
很烦人。特别是因为 Python 不使用 32 位按位操作数。
我知道我基本上是在尝试改变语言的本质。所以也许我问的是如果你必须在 python 中做 32 位的东西你会怎么做。
最佳答案
一些选项:
- 使用 Cython。您可以在那里声明一个 native 32 位 int 类型,您甚至可以获得将纯数字代码编译为(非常)快速的 C 代码的优势。
- 使用单个元素的
numpy
数组:np.zeros((1,), dtype=np.int32)
。如果您只使用就地操作(+=
、*=
等),这将像 32 位 int 类型一样工作。请注意,如果您曾经使用过常规二元运算符(例如myint + 3
),您可能会进行类型提升或转换,结果将不再是int32
. - 使用
ctypes.c_int32
。这是 Python 的内置功能,但不支持数学运算,因此您必须自己包装和解包(例如newval = c_int32(v1.value + v2.value)
)。 - 使用类似
fixedint
的库(无耻的插件),它提供固定整数类,这些类通过操作保持固定大小,而不是衰减到int
。fixedint
是专门为固定宽度的按位数学而设计的。在这种情况下,您将使用fixedint.Int32
。
一些不太理想的选择:
struct
:如果您的输入超出范围,则抛出错误。您可以使用unpack('i', pack('I', val & 0xffffffff))[0]
解决此问题,但这确实很笨拙。array
:如果您尝试存储超出范围的值,则会抛出错误。比struct
更难解决。手动 bitmashing。对于 unsigned 32 位 int,这只是添加很多
& 0xffffffff
的问题,这还算不错。但是,Python 没有任何内置方法可以将值包装为带符号的 32 位 int,因此您必须编写自己的int32
转换函数并用它包装所有操作:def to_int32(val): val &= ((1<<32)-1) if val & (1<<31): val -= (1<<32) return val
演示您的选择:
赛通
cpdef int munge(int val):
cdef int x
x = val * 32
x += 0x7fffffff
return x
另存为 int_test.pyx
并使用 cythonize -a -i int_test.pyx
进行编译。
>>> import int_test
>>> int_test.munge(3)
-2147483553
NumPy
import numpy as np
def munge(val):
x = val.copy()
x *= 32
x += 0x7fffffff
return x
def to_int32(val):
return np.array((val,), dtype=np.int32)
print(munge(to_int32(3)))
# prints [-2147483553]
类型
from ctypes import c_int32
def munge(val):
x = c_int32(val.value * 32)
x = c_int32(x.value + 0x7fffffff)
return x
print(munge(c_int32(3)))
# prints c_int(-2147483553)
固定整数
import fixedint
def munge(val):
x = val * 32
x += 0x7fffffff
return x
print(munge(fixedint.Int32(3)))
# prints -2147483553
关于python - 使用 32 位整数和操作数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53136516/