我想将值表示为64位有符号long
,这样大于(2 ** 63)-1的值表示为负数,但Python long
具有无限精度。对我来说,实现这一目标是否有“快速”的方式?
答案 0 :(得分:13)
您可以使用ctypes.c_longlong
:
>>> from ctypes import c_longlong as ll
>>> ll(2 ** 63 - 1)
c_longlong(9223372036854775807L)
>>> ll(2 ** 63)
c_longlong(-9223372036854775808L)
>>> ll(2 ** 63).value
-9223372036854775808L
如果您确定目标计算机上signed long long
的宽度为64位,那么这只是 一个选项。
编辑: jorendorff's idea定义64位数字的类很有吸引力。理想情况下,您希望最大限度地减少显式类创建的数量。
使用c_longlong
,您可以执行以下操作(注意:仅限Python 3.x):
from ctypes import c_longlong
class ll(int):
def __new__(cls, n):
return int.__new__(cls, c_longlong(n).value)
def __add__(self, other):
return ll(super().__add__(other))
def __radd__(self, other):
return ll(other.__add__(self))
def __sub__(self, other):
return ll(super().__sub__(other))
def __rsub__(self, other):
return ll(other.__sub__(self))
...
这样ll(2 ** 63) - 1
的结果确实是9223372036854775807
。这种结构可能会导致性能下降,因此根据您想要做的事情,定义如上所述的类可能不值得。如有疑问,请使用timeit
。
答案 1 :(得分:11)
您可以使用numpy吗?它有一个int64类型,完全符合你的要求。
In [1]: import numpy
In [2]: numpy.int64(2**63-1)
Out[2]: 9223372036854775807
In [3]: numpy.int64(2**63-1)+1
Out[3]: -9223372036854775808
与ctypes示例不同,它对用户是透明的,并且它用C编码,因此它比在Python中滚动自己的类更快。 Numpy可能比其他解决方案更大,但是如果你正在进行数值分析,你会很感激它。
答案 2 :(得分:3)
最快的事情可能是自己将结果截断为64位:
def to_int64(n):
n = n & ((1 << 64) - 1)
if n > (1 << 63) - 1:
n -= 1 << 64
return n
您当然可以定义自己的数字类型,每次进行任何算术运算时都会自动执行此操作:
class Int64:
def __init__(self, n):
if isinstance(n, Int64):
n = n.val
self.val = to_int64(n)
def __add__(self, other):
return Int64(self.val + other)
def __radd__(self, other):
return Int64(other + self.val)
def __sub__(self, other):
return Int64(self.val - other)
...
但实施起来并不是特别“快速”。
答案 3 :(得分:1)
看看ctypes模块,它用于从python调用外部DLL /库。 有一些数据类型对应于C类型,例如
class c_longlong