Python中整数溢出的模拟

Python中整数溢出的模拟,python,ctypes,integer-overflow,Python,Ctypes,Integer Overflow,Python2有两个整数数据类型int和long,并根据需要在它们之间自动转换,特别是为了避免整数溢出 我正在用Python模拟一个C函数,我想知道是否有标准的方法来重新启用整数溢出。暂时来说,我用了 overflow_point = maxint + 1 if value > overflow_point: value -= 2 * overflow_point 有没有更标准的方法来做同样的事情?我不知道有没有一种方便的方法可以在本机上做这件事,因为它通常不被认为是一个问题,所

Python2有两个整数数据类型
int
long
,并根据需要在它们之间自动转换,特别是为了避免整数溢出

我正在用Python模拟一个C函数,我想知道是否有标准的方法来重新启用整数溢出。暂时来说,我用了

overflow_point = maxint + 1
if value > overflow_point:
    value -= 2 * overflow_point

有没有更标准的方法来做同样的事情?

我不知道有没有一种方便的方法可以在本机上做这件事,因为它通常不被认为是一个问题,所以python开发人员不想在其中构建它。我认为你这样做很好。您甚至可以对
int
内置类型进行子类化,并覆盖,
\uuuuuu sub\uuuu()
等操作符方法以包含您的功能,但这可能有些过分。

我认为基本思想是合理的,但需要一些调整:

  • 您的函数不会在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 int_溢出(val):
    如果不是-sys.maxint-1函数是否使用除法或右位移位?如果没有,那么你就没有 在计算的每个阶段都需要担心溢出,因为 您将始终得到模为2^32或2^64的“正确”答案。之前 返回结果(或在进行除法或右移位之前) 您可以使用某种方法将其规格化回标准整数范围 像


    此函数应将数字转换为硬件整数。根据您的应用程序,您可能需要在操作的每个阶段之间应用此功能

    def correct(value, bits, signed):
        base = 1 << bits
        value %= base
        return value - base if signed and value.bit_length() == bits else value
    
    作为如何使用它们的一个例子,一个bug可能会在C中重现。如果一个人要用一个字节来打印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()
    
    #/usr/bin/env蟒蛇3
    def main():
    计数器=0
    当计数器<256时:
    打印(计数器)
    计数器=字节(计数器+1)
    def正确(值、位、有符号):
    base=1使用NumPy(它是用C编写的,并公开本机级别的整数)。NumPy具有以下整数类型:

    有符号整数:

    • np.int8
    • np.int16
    • np.int32
    无符号整数:

    • np.uint8
    • np.uint16
    • np.uint32
    例如(注意它在整数值127之后溢出):

    将numpy导入为np
    计数器=np.int8(0)
    一=np.int8(1)
    对于范围(130)内的i:
    打印(类型(计数器)、计数器)
    计数器=计数器+1
    

    例如,在任何时候,您都可以使用
    int(counter)
    将其转换回Python整数。

    您可以创建自己的数字数据类型(类),定义如何执行加法、减法、乘法和除法。您的目标是什么?包括未定义行为的模语义或C语义?重载
    \uuuu setattr\uuuu
    将实现什么?你从来没有在整数上设置属性。编辑以澄清我的意图。子类可以重写uuu add uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。当然,这是一种严重的过度杀伤力。int对象应该是不可变的<代码>\uuuu添加\uuuuu
    应该返回一个没有设置任何属性的新对象。啊,好的,很好。因此,它可能会计算溢出值并返回该值。我会改变的。谢谢你的反馈,我对python反射很生疏:)+1。遗憾的是,python中的开销太大,实际上无法成为一个可用的解决方案。为了完整起见,请您使用函数添加几个示例?@GabrielStaples您觉得这个示例怎么样?如果您希望更改或添加更多内容,可以编辑答案以进行改进。
    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)
    )
    
    #! /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()