Python 2 有两种整数数据类型int
和long
,并根据需要自动在它们之间进行转换,尤其是为了避免整数溢出。
我正在用 Python 模拟 C 函数,想知道是否有标准方法可以重新启用整数溢出。对于随机数,我用过
overflow_point = maxint + 1
if value > overflow_point:
value -= 2 * overflow_point
有没有更标准的方法来做同样的事情?
Python 2 有两种整数数据类型int
和long
,并根据需要自动在它们之间进行转换,尤其是为了避免整数溢出。
我正在用 Python 模拟 C 函数,想知道是否有标准方法可以重新启用整数溢出。对于随机数,我用过
overflow_point = maxint + 1
if value > overflow_point:
value -= 2 * overflow_point
有没有更标准的方法来做同样的事情?
我认为基本想法是合理的,但需要一些调整:
sys.maxint+1
,但它应该;sys.maxint
一次操作可以超过数倍;-sys.maxint-1
也需要考虑。考虑到这一点,我想出了以下几点:
import sys
def int_overflow(val):
if not -sys.maxint-1 <= val <= sys.maxint:
val = (val + (sys.maxint + 1)) % (2 * (sys.maxint + 1)) - sys.maxint - 1
return val
此函数应将您的数字转换为看起来像硬件整数。根据您的应用程序,您可能需要在操作的每个阶段之间应用此功能。
def correct(value, bits, signed):
base = 1 << bits
value %= base
return value - base if signed and value.bit_length() == bits else value
以下快捷功能可能会派上用场,以将值“转换”到适当的范围:
byte, sbyte, word, sword, dword, sdword, qword, sqword = (
lambda v: correct(v, 8, False), lambda v: correct(v, 8, True),
lambda v: correct(v, 16, False), lambda v: correct(v, 16, True),
lambda v: correct(v, 32, False), lambda v: correct(v, 32, True),
lambda v: correct(v, 64, False), lambda v: correct(v, 64, True)
)
作为如何使用它们的一个示例,可以重现一个在 C 中可能会看到的错误。如果要编写一个 for 循环,使用一个字节打印出 0 - 255,那么循环可能永远不会结束。下面的程序演示了这个问题:
#! /usr/bin/env python3
def main():
counter = 0
while counter < 256:
print(counter)
counter = byte(counter + 1)
def correct(value, bits, signed):
base = 1 << bits
value %= base
return value - base if signed and value.bit_length() == bits else value
byte, sbyte, word, sword, dword, sdword, qword, sqword = (
lambda v: correct(v, 8, False), lambda v: correct(v, 8, True),
lambda v: correct(v, 16, False), lambda v: correct(v, 16, True),
lambda v: correct(v, 32, False), lambda v: correct(v, 32, True),
lambda v: correct(v, 64, False), lambda v: correct(v, 64, True)
)
if __name__ == '__main__':
main()
您的函数使用除法还是右位移?如果不是,那么您无需担心计算的每个阶段都会溢出,因为您将始终得到模 2^32 或 2^64 的“正确”答案。在返回结果之前(或在进行除法或右位移之前),您可以使用类似的方法归一化回标准整数范围
import sys
HALF_N = sys.maxint + 1
N = HALF_N * 2
def normalize(value):
return (value + HALF_N) % N - HALF_N
我不知道有一种方便的方法可以在本地执行此操作,因为它通常不被认为是一个问题,所以它不是 python 开发人员想要构建的东西。我认为你这样做的方式很好。您甚至可以继承int
内置类型并覆盖__add__()
,__sub__()
等运算符方法以包含您的功能,但这可能是矫枉过正。
使用 NumPy(用 C 语言编写并公开本机机器级整数)。NumPy 有以下整数类型:
有符号整数:
无符号整数:
例如(注意它在整数值 127 之后溢出):
import numpy as np
counter = np.int8(0)
one = np.int8(1)
for i in range(130):
print(type(counter), counter)
counter = counter + one
例如,在任何时候,您都可以使用 just 转换回 Python 整数int(counter)
。