# [Python-checkins] python/nondist/sandbox/decimal Decimal.py, 1.34, 1.35

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Wed Jun 30 21:47:05 EDT 2004

```Update of /cvsroot/python/python/nondist/sandbox/decimal
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8494

Modified Files:
Decimal.py
Log Message:
* Fix broken hash function so that now:
hash(2.300) == hash(2.3) == hash(2300e-2)
hash(0) == hash(-0)
hash(i) == hash(int(i)) whenever i is an integer
signs and exponents are taken into account

* Add or improve more docstrings and doctests.

Index: Decimal.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/decimal/Decimal.py,v
retrieving revision 1.34
retrieving revision 1.35
diff -C2 -d -r1.34 -r1.35
*** Decimal.py	30 Jun 2004 19:11:40 -0000	1.34
--- Decimal.py	1 Jul 2004 01:47:03 -0000	1.35
***************
*** 16,35 ****
#    Improve docstrings and add more doctests
#    Improve the Context API

"""
! This is a stab at a decimal arithmetic module based on the decimal
! arithmetic ANSI standard X3.274-1996.

! Most of the information used to create this module was helpfully provided
! by Mike Cowlishaw's work at
! http://www2.hursley.ibm.com/decimal/
! The rest comes from Tim Peters's FixedPoint.py, particularly the string
! conversion routine and general Pythonic practices.

! In the current form of Decimal(), precision is finite but unbounded, with
! the exception of division and square roots.

! Here are some simple test cases that show how to use Decimal.  There
! is a separate full-blown test harness (run Test(testdatadir).test())

>>> from Decimal import *
--- 16,47 ----
#    Improve docstrings and add more doctests
#    Improve the Context API
+ #    Provide a clean way of attaching monetary format representations

"""
! This is an implementation of decimal floating point arithmetic based on
! the General Decimal Arithmetic Specification:

!     www2.hursley.ibm.com/decimal/decarith.html

! IEEE standard 854-1987:

!     www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
!
! and ANSI standard X3.274-1996:
!
!     www.rexxla.org/Standards/ansi.html
!
!
! Decimal floating point has finite precision with arbitrarily large bounds.
!
! The purpose of the module is to support arithmetic using familiar
! "schoolhouse" rules and to avoid the some of tricky representation
! issues associated with binary floating point.  The package is especially
! useful for financial applications or for contexts where users have
! expectations that are at odds with binary floating point (for instance,
! in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
! of the expected Decimal("0.00") returned by decimal floating point).
!
! Here are some examples of using the decimal module:

>>> from Decimal import *
***************
*** 447,458 ****

def __init__(self, value="0", context=None):
!         """Initialize the Decimal class.
!
!         Accepts several types of input:

!         string
!         list/tuple in form (sign, (digit_list), exponent)
!         Decimal instance
!         long, int
"""
if context is None:
--- 459,472 ----

def __init__(self, value="0", context=None):
!         """Create a decimal point instance.

!         >>> Decimal('3.14')              # string input
!         Decimal("3.14")
!         >>> Decimal((0, (3, 1, 4), -2))  # tuple input (sign, digit_tuple, exponent)
!         Decimal("3.14")
!         >>> Decimal(314)                 # int or long
!         Decimal("314")
!         >>> Decimal(Decimal(314))        # another decimal instance
!         Decimal("314")
"""
if context is None:
***************
*** 684,697 ****

def __hash__(self):
!         """Hashes whole numbers to their long equivalent.
!
!         Numbers equal in value hash to the same value if exp>0, only if
!         they have the same precision if not.
!         XXX Doesn't make too much sense-- hash(10) = hash(1e1) != hash(100e-1)
!         """
!         if self._exp >= 0:
!             return hash(int(self))
!         else:
!             return hash( (self._sign, self._int, self._exp) )

def as_tuple(self):
--- 698,710 ----

def __hash__(self):
!         """x.__hash__() <==> hash(x)"""
!         # Decimal integers must hash the same as the ints
!         # Non-integer decimals are normalized and hashed as strings
!         # Normalization assures that hast(100E-1) == hash(10)
!         i = int(self)
!         if self == Decimal(i):
!             return hash(i)
!         assert self.__nonzero__()   # '-0' handled by integer case
!         return hash(str(self.normalize()))

def as_tuple(self):
***************
*** 703,717 ****

def __repr__(self):
!         """Represents the number as an instance of Decimal.
!
!         Not pretty, but eval(repr(self)) == self
!         """
return 'Decimal("%s")' % str(self)

def __str__(self, eng = 0, context=None):
!         """Return the string representation of the number.

!         It is written in scientific notation. Because it represents all the
!         number information, can be used from repr() also.
"""

--- 716,727 ----

def __repr__(self):
!         """Represents the number as an instance of Decimal."""
!         # Invariant:  eval(repr(d)) == d
return 'Decimal("%s")' % str(self)

def __str__(self, eng = 0, context=None):
!         """Return string representation of the number in scientific notation.

!         Captures all of the information in the underlying representation.
"""

```