Python自定义数字类型:环绕数字
希望这个问题能简单点;我脑子一片空白。
有没有可能或者说这样做是否实际,就是创建一个类,这个类只表示一个普通的数字值(比如浮点数、整数等),当这个值小于等于0的时候,它会自动变成一个很大的值,就像C语言中的无符号值那样?
“这完全是疯了”也是一个可以接受的回答!
说说“合理”的使用场景;比如在评估某种“努力”成本时,负的“成本”虽然理论上可以,但在实际中是无效的,通常会检查每个值,如果小于等于0就改成最大值。
与其进行这么多额外的比较,不如让这个成本值自带这种行为。
3 个回答
0
我最近写了类似的东西,并在博客上分享了。简单来说,为什么会想要这样做,原作者已经提到了:你可能想用Python来模拟C语言或x86汇编代码的行为,这些操作通常是以2的32次方为模数进行的,或者其他的2的幂次方。此外,你可能还想要一个可以实现有限域元素的类型。下面的代码就能做到这两点。
我知道使用这种高级的元类有点过于复杂,但我想让代码尽量简洁,而元类是保持代码简短的一个简单方法。
class wrapped(type):
def __new__(cls, name, bases, nmspc, mod=None, bits=None, hexrep=False, signed=False):
assert int in bases[0].__mro__
if None not in (mod, bits) and 1 << bits != mod:
raise ValueError('incompatible mod and bits argument.')
mod = mod or bits and 1 << bits
if mod:
for op in 'add', 'and', 'floordiv', 'lshift', 'mod', 'mul', 'or', 'rshift', 'sub', 'xor':
opname = F'__{op}__'
nmspc[F'__r{op}__'] = nmspc[opname] = lambda self, them, op=getattr(int, opname): (
self.__class__(op(self, them)))
nmspc['__rtruediv__'] = nmspc['__truediv__'] = lambda self, them, p=int.__pow__: (
self.__class__(self * p(them, -1, mod)))
nmspc['__pow__'] = lambda self, them, op=int.__pow__: self.__class__(op(self, them, mod))
nmspc['__inv__'] = lambda self, op=int.__invert__: self.__class__(op(self))
nmspc['__neg__'] = lambda self, op=int.__neg__: self.__class__(op(self))
nmspc.update(mod=mod, signed=signed)
if hexrep is True:
nib, up = divmod((mod.bit_length() - 1) - 1, 4)
nib += bool(up)
nmspc['__repr__'] = lambda self: F'{self:#0{nib}x}'
return type.__new__(cls, name, bases, nmspc)
def __call__(cls, value=0, *args, **kwargs):
if isinstance(value, int):
value = value % cls.mod
if cls.signed and (value & (cls.mod >> 1)):
value -= cls.mod
return type.__call__(cls, value)
return cls(int(value, *args, **kwargs))
class wrap(int, metaclass=wrapped):
pass
你可以这样使用它:
In [2]: class uint32(wrap, mod=(1 << 32), hexrep=True): pass
In [3]: a = uint32(0xC0C4C01A)
In [4]: a
Out[4]: 0x0C0C4C01A
In [5]: a ** 0x00F
Out[5]: 0x02A028000
或者,如果你不喜欢十六进制的表示方式,只需在你新定义的整数类型中不把hexrep
设置为True
即可。
0
首先,Python 里一般没有 maxint
这个值,因为它的整数类型是没有上限的。当整数超过 sys.maxint
的时候,它会变成 long
类型。不过,如果你想要实现特定的功能,可以通过编写描述符来实现,如果你希望这个功能是类属性的话;如果你希望它是实例属性的话,就用属性来实现。
3
找到了答案
使用Numpy的无符号整型可以解决这个问题。
import numpy.uint32
valueA=uint32(5)
valueB=uint32(-5)
assert valueA < valueB