使用32位整数和操作数

时间:2018-11-03 23:45:23

标签: python int bitwise-operators bit

是否可以以某种方式重写或重载python中的整数/数字的标准实现,使其像32位整数一样起作用。

a: int
a = 4076863488
>>> -218103808

还是可以以某种方式定义不能更改类型的变量?做类似x: int的事情吗? 我要这样做是因为在每个位操作和赋值上写ctypes.c_int32(n)很烦人。尤其是因为Python不使用32位按位操作数。

我知道我基本上是在尝试更改语言的性质。所以也许我在问如果您必须在python中执行32位操作,您会怎么做。

1 个答案:

答案 0 :(得分:4)

一些选项:

  • 使用Cython。您可以在那里声明一个本机的32位int类型,甚至可以得到纯数字代码被编译为(非常)快速C代码的优点。
  • 使用包含单个元素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

您的选项的演示

Cython

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

NumPy

>>> import int_test
>>> int_test.munge(3)
-2147483553

ctypes

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]

fixedint

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)