Hi Dan, I find that when doing bit-twiddling in pure Python, fixed-width integer support is an extremely handy capability to have in Python regardless of what the apologists (for its absence) say.
I added some stuff to fixedint.py to make >>> x=SByte(80) >>> x+200 fixedint.SignedType(8)(24) the above work. Perhaps you can review the code to see if there are any major flaws in it? Right after I started using it, I realized there has to be a lot more thought put into the conventions for the coecion rules. What should >>> x=SByte(80) >>> 200+x return for example... ? ----- START OF CODE ----- import operator def _toFixedUnsigned(n, b): "Truncate n to a b-bit unsigned long." return n & ((1L << b) - 1) # bitmask of b 1's def _toFixedSigned(n, b): "Truncate n to a b-bit signed long." result = _toFixedUnsigned(n, b) if result >= (1L << b - 1): # More than "maxint"? result -= 1L << b # Then wrap around. return result class _Integer(object): "Abstract base class for SignedType and UnsignedType." # Numeric conversions def __long__(self): return self._value def __int__(self): return int(self._value) def __float__(self): return float(self._value) def __nonzero__(self): return self._value != 0 # String conversions. def __str__(self): return str(self._value) # Arithmetic def __pos__(self): return self def __neg__(self): return type(self)(-self._value) def __add__(self, other): if isinstance(other, type(self)): return type(self)(self._value + other._value) else: return type(self)(self._value + self.__class__(other)._value) def __sub__(self, other): if isinstance(other, type(self)): return type(self)(self._value - other._value) else: return type(self)(self._value - self.__class__(other)._value) def __mul__(self, other): if isinstance(other, type(self)): return type(self)(self._value * other._value) else: return type(self)(self._value * self.__class__(other)._value) def __floordiv__(self, other): if isinstance(other, type(self)): return type(self)(self._value // other._value) else: return type(self)(self._value // self.__class__(other)._value) def __mod__(self, other): if isinstance(other, type(self)): return type(self)(self._value % other._value) else: return type(self)(self._value % self.__class__(other)._value) def __divmod__(self, other): return self // other, self % other # Relational def __cmp__(self, other): return cmp(long(self), other) # Bit-bashing def __lshift__(self, other): return type(self)(self._value << other) def __rshift__(self, other): return type(self)(self._value >> other) def __invert__(self): return type(self)(~self._value) def __and__(self, other): if isinstance(other, type(self)): return type(self)(self._value & other._value) else: return type(self)(self._value & self.__class__(other)._value) def __or__(self, other): if isinstance(other, type(self)): return type(self)(self._value | other._value) else: return type(self)(self._value | self.__class__(other)._value) def __xor__(self, other): if isinstance(other, type(self)): return type(self)(self._value ^ other._value) else: return type(self)(self._value ^ self.__class__(other)._value) _utypes = {} def UnsignedType(bits): "Returns a fixed-width unsigned int type with the given number of bits." if bits in _utypes: return _utypes[bits] else: class unsigned(_Integer): __doc__ = '%d-bit unsigned integer type' % bits def __init__(self, value): self._value = _toFixedUnsigned(value, bits) def __repr__(self): return 'fixedint.UnsignedType(%d)(%d)' % (bits, self._value) return unsigned Byte = UnsignedType(8) UShort = UnsignedType(16) UInt = UnsignedType(32) ULong = UnsignedType(64) _stypes = {} def SignedType(bits): "Returns a fixed-width signed int type with the given number of bits." if bits in _stypes: return _stypes[bits] else: class signed(_Integer): __doc__ = '%d-bit signed integer type' % bits def __init__(self, value): self._value = _toFixedSigned(value, bits) def __repr__(self): return 'fixedint.SignedType(%d)(%d)' % (bits, self._value) return signed SByte = SignedType(8) Short = SignedType(16) Int = SignedType(32) Long = SignedType(64) -- http://mail.python.org/mailman/listinfo/python-list