我想将一个值表示为一个64位有符号的long
,使得大于(2 ** 63)-1的值表示为负数,但Python long
具有无限精度。是否有一个“快速”的方式来实现这一目标?Python类型长对C'long long'
11
A
回答
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
。
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)
...
但这并不是特别“快速”实施。
1
查看ctypes模块,它用于从python调用外部DLL /库。 那里,C类型对应的一个一些数据类型,例如
类c_longlong
10
你能使用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可能比其他解决方案更大,但如果您正在进行数值分析,您会欣赏它。
相关问题
- 1. 无符号长long int类型战俘
- 2. “unsigned long int类型”和“无符号长long int型的收入分配问题
- 3. 'long long long'对于GCC来说太长使用log4cpp
- 4. long类型溢出
- 5. 类型“long long”总是64位?
- 6. 联盟为unsigned long long int类型投
- 7. 后缀LL为long long类型
- 8. 什么是Java类型long long
- 9. 为什么数据类型长期支持等于long long的最大数量?
- 10. C++ Casting类型(SLODWORD和long)
- 11. 主键类型:int vs long
- 12. 格式指定类型'无符号long long',但参数的类型为'unsigned int'
- 13. 错误:类型“长*”不能分配给类型的实体“长”
- 14. 一个奇怪的C++错误,也许它是相对于long long类型
- 15. Python:“不支持的操作数类型为+:'long'和'numpy.float64'”
- 16. 双类型到长类型
- 17. 为什么serialVersionUID的类型为Serializable类的long类型
- 18. 数据类型转换(无符号long long到char)
- 19. Java:做自己的数据类型? (例如long long double?)
- 20. 在C++中是否有比long long int更大的类型?
- 21. 类型转换为unsigned long long到字符指针用C
- 22. C中的64位数据类型(long long)的按位运算?
- 23. 不能转换的boost ::拉姆达:: ...为long long unsigned int类型
- 24. 什么样的数据类型是“long long”?
- 25. 如何初始化一个无符号的long long类型?
- 26. 改变“类型” Python对象
- 27. 如何让Timestamp对象在JSON中的long类型中显示?
- 28. 运算符 - 未定义为参数类型long,对象
- 29. 的mysql-python的fetchrow带来:类型错误: '长' 对象不是可调用
- 30. 对象类型'长'没有len()