Некоторые опции:
- Используйте Cython. Вы можете объявить собственный 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
.
Ручная битмашинг. Для 32-битного целого без знака это просто вопрос добавления & 0xffffffff
, что не так уж и плохо. Но в Python нет встроенного способа обернуть значение в 32-битное целое со знаком, поэтому вам придется написать собственную функцию преобразования int32
и обернуть все свои операции с ней:
def to_int32(val):
val &= ((1<<32)-1)
if val & (1<<31): val -= (1<<32)
return val
Демонстрация ваших вариантов:
Cython
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]
ctypes
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)
fixedint
import fixedint
def munge(val):
x = val * 32
x += 0x7fffffff
return x
print(munge(fixedint.Int32(3)))
# prints -2147483553