Rationale for core Python numeric types

Dan Bishop danb_83 at yahoo.com
Fri Jul 16 17:48:12 EDT 2004


"Batista, Facundo" <FBatista at uniFON.com.ar> wrote in message news:<mailman.481.1089982235.5135.python-list at python.org>...
> [mfein2 at earthlink.net]
> 
> #- rationale for core Python numeric types? Should I just go 
> #- dunk my head
> #- in a pail of water and take a deep breath?
> 
> No. You should write a PEP.
> 
> If gets accepted, and you or somebody implements it,

Not necessarily in that order :-)

>>> import fixedint
>>> a = fixedint.UInt(3)
>>> b = fixedint.UInt(2)
>>> a + b
fixedint.UnsignedType(32)(5)
>>> a - b
fixedint.UnsignedType(32)(1)
>>> b - a
fixedint.UnsignedType(32)(4294967295)
>>> a << 24
fixedint.UnsignedType(32)(50331648)
>>> a << 34
fixedint.UnsignedType(32)(0)
>>> c = fixedint.Int(4)
>>> a + c
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unsupported operand type(s) for +: 'unsigned' and 'signed'
>>> int(a) + int(c)
7

And here's the fixedint.py module I just wrote:

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)
      return NotImplemented
   def __sub__(self, other):
      if isinstance(other, type(self)):
         return type(self)(self._value - other._value)
      return NotImplemented
   def __mul__(self, other):
      if isinstance(other, type(self)):
         return type(self)(self._value * other._value)
      return NotImplemented
   def __floordiv__(self, other):
      if isinstance(other, type(self)):
         return type(self)(self._value // other._value)
      return NotImplemented
   def __mod__(self, other):
      if isinstance(other, type(self)):
         return type(self)(self._value % other._value)
      return NotImplemented
   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)
      return NotImplemented
   def __or__(self, other):
      if isinstance(other, type(self)):
         return type(self)(self._value | other._value)
      return NotImplemented
   def __xor__(self, other):
      if isinstance(other, type(self)):
         return type(self)(self._value ^ other._value)
      return NotImplemented

_utypes = {}

def UnsignedType(bits):
   "Returns a fixed-with 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)



More information about the Python-list mailing list