在Python中启用整数溢出

时间:2019-05-26 14:24:02

标签: python integer-overflow

我想创建一个2D环境,其中顶部和底部以及左侧和右侧连接在一起(类似于Torus或Doughnut)。但是,我不想在每个帧上检查对象的x / y坐标,而是想使用整数溢出对其进行仿真。
尽管可以完成常规迭代(如下面的示例代码所示),但是仅对某些变量启用溢出可能会稍微有效(尽管很危险),尤其是在每个帧/迭代中处理数百或数千个对象时。 / p>

我可以找到一些示例,它们也可以模拟Python中的整数溢出,例如this。但是,我正在寻找可以通过在某些变量中启用溢出并通常跳过检查来实现溢出的功能。

# With normal checking of every instance
import random

width = 100
height = 100

class item():
    global width, height

    def __init__(self):
        self.x = random.randint(0, width)
        self.y = random.randint(0, height)

items = [item for _ in range(10)] # create 10 instances

while True:
    for obj in items:
        obj.x += 10
        obj.y += 20
        while obj.x > width:
            obj.x -= width
        while obj.y > height:
            obj.y -= height
        while obj.x < width:
            obj.x += width
        while obj.y < height:
            obj.y += height

我只想模拟某些特定类/对象的整数溢出。有没有办法让一些变量自动溢出并循环回到其最小值/最大值?

2 个答案:

答案 0 :(得分:1)

您可以使用properties来实现具有自定义行为的getter / setter方法。例如这样的

import random

WIDTH = 100
HEIGHT = 100


class item():

    def __init__(self):
        self._x = random.randint(0, WIDTH - 1)
        self._y = random.randint(0, HEIGHT - 1)

    def __str__(self):
        return '(%r, %r)' % (self._x, self._y)

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, new_value):
        self._x = new_value % WIDTH

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, new_value):
        self._y = new_value % HEIGHT


items = [item() for _ in range(10)]

while True:
    for pos in items:
        pos.x += 10
        pos.y += 20
        print(pos)  # to show the results

答案 1 :(得分:0)

使用描述符,您可以定义对象属性所需的行为。在行与行之间阅读听起来好像您希望属性表现出value = value % maximum的行为。

from weakref import WeakKeyDictionary

class MaxValue:
    '''A descriptor whose value will be: value modulo maximum.'''
    def __init__(self, maximum, default=0):
        self.maximum = maximum
        self.default = default
        self.data = WeakKeyDictionary()

    def __get__(self, instance, owner):
        return self.data.get(instance, self.default)

    def __set__(self, instance, value):
        self.data[instance] = value % self.maximum

描述符应该是类属性。对于示例类:

import random
width = 100
height = 100

class Item:
##    global width, height
    x = MaxValue(width)
    y = MaxValue(height)

    def __init__(self):
        self.x = random.randint(0, width)
        self.y = random.randint(0, height)
    def __str__(self):
        return f'({self.x:>3},{self.y:>3})'

示例:

items = [Item() for _ in range(5)]
print(','.join(f'{item}' for item in items))
for n in range(15):
    for item in items:
        item.x += 10
        item.y += 20
    print(','.join(f'{item}' for item in items))

>>>
( 74,  6),( 49, 19),( 56, 10),( 72, 16),( 83, 16)
( 84, 26),( 59, 39),( 66, 30),( 82, 36),( 93, 36)
( 94, 46),( 69, 59),( 76, 50),( 92, 56),(  3, 56)
(  4, 66),( 79, 79),( 86, 70),(  2, 76),( 13, 76)
( 14, 86),( 89, 99),( 96, 90),( 12, 96),( 23, 96)
( 24,  6),( 99, 19),(  6, 10),( 22, 16),( 33, 16)
( 34, 26),(  9, 39),( 16, 30),( 32, 36),( 43, 36)
( 44, 46),( 19, 59),( 26, 50),( 42, 56),( 53, 56)
( 54, 66),( 29, 79),( 36, 70),( 52, 76),( 63, 76)
( 64, 86),( 39, 99),( 46, 90),( 62, 96),( 73, 96)
( 74,  6),( 49, 19),( 56, 10),( 72, 16),( 83, 16)
( 84, 26),( 59, 39),( 66, 30),( 82, 36),( 93, 36)
( 94, 46),( 69, 59),( 76, 50),( 92, 56),(  3, 56)
(  4, 66),( 79, 79),( 86, 70),(  2, 76),( 13, 76)
( 14, 86),( 89, 99),( 96, 90),( 12, 96),( 23, 96)
( 24,  6),( 99, 19),(  6, 10),( 22, 16),( 33, 16)
>>>

不是我的想法-在Python Descriptors Demystified


每个MaxValue实例都需要跟踪(或知道)每个Item实例的值-Item.x需要知道 x个实例Itemab,...的c 值。字典很方便,并且使用了WeakKeyDictionary,因此,如果字典是对Item实例的唯一引用,则可以对该实例进行垃圾回收。

此解决方案减轻了为每个共享行为的属性编写 getter / setter 的需求。