是否可以以某种方式重写或重载python中的整数/数字的标准实现,使其像32位整数一样起作用。
a: int
a = 4076863488
>>> -218103808
还是可以以某种方式定义不能更改类型的变量?做类似x: int
的事情吗?
我要这样做是因为在每个位操作和赋值上写ctypes.c_int32(n)
很烦人。尤其是因为Python不使用32位按位操作数。
我知道我基本上是在尝试更改语言的性质。所以也许我在问如果您必须在python中执行32位操作,您会怎么做。
答案 0 :(得分:4)
一些选项:
numpy
的{{1}}数组。如果您仅使用过就地操作(np.zeros((1,), dtype=np.int32)
,+=
等),它将像32位int类型一样工作。请注意,如果您使用常规的二进制运算符(例如*=
),则可能会进行类型提升或转换,并且结果将不再是myint + 3
。int32
。这是Python内置的,但不支持数学运算,因此您必须自己包装和解包(例如ctypes.c_int32
)。fixedint
(无耻插件)的库,该库提供固定整数类,这些类通过操作保持固定大小,而不是衰减到newval = c_int32(v1.value + v2.value)
。 int
是专门为设计固定宽度按位数学而设计的。在这种情况下,您将使用fixedint
。一些不太理想的选择:
fixedint.Int32
:如果您的输入超出范围,则会引发错误。您可以使用struct
解决此问题,但这确实很麻烦。unpack('i', pack('I', val & 0xffffffff))[0]
:如果您尝试存储超出范围的值,则会引发错误。比array
更难解决。手动位打。使用无符号的32位int,这只是添加struct
的问题,这还不错。但是,Python没有任何将值包装到带符号的32位int的内置方法,因此您必须编写自己的& 0xffffffff
转换函数并使用它包装所有操作:>
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
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)