August 28, 2003
Python fixed decimal types and immutability

David is learning Python. He's posted some of his observations, many of which are very interesting - see Python first impressions, Python data hiding and Trust me: I'm a programmer.

Clearly, David is also aware of the problems with using floating point values to hold financial values, since he's found Ng Pheng Siong's Money class. I recommended that he look at FixedPoint instead, since it's pretty much the de facto standard.

But there's one thing that both modules get wrong. As Ka-Ping Yee pointed out on Python-Dev, it's important that any fixed point numeric type be immutable. Both FixedPoint and Ng Pheng Siong's BigDecimal are mutable. For one thing, this means that they cannot safely be used as dictionary keys. But there are other reasons for favouring immutability - simplicity, inherent thread safety, and safe object sharing spring to mind.

I don't know if there is any movement towards including FixedPoint, or something like it, in Python's standard library in version 2.4. I certainly hope so.

Posted to Python by Simon Brunning at August 28, 2003 11:30 AM
Comments

Yes, I much prefer the reassurance of immutability. In Java, it also lets you use the "==" operator instead of the equals(...) method; I wonder if that is another bit of awkwardness that Python does away with. I hope so.

I add my yet-feeble voice to the call for Money, or the more generic FixedPoint, to be added to a standard library. Rewriting that stuff is getting boring.

I must find out what Python does about time points; I am always writing Java code to represent time at various levels of granularity.

Posted by: David Pinn on August 28, 2003 12:27 PM

Ah, dates and times.

Well, up until Python 2.2, everyone used mxDateTime - see http://www.egenix.com/files/python/mxDateTime.html . But a new datetime module was added in 2.3 - http://www.python.org/doc/2.3/whatsnew/node18.html .

I'll be sticking with mxDateTime myself, partly 'cos it has more functionality (see http://www.brunningonline.net/simon/blog/archives/000868.html ), partly 'cos I don't want to change working code, and partly 'cos Python 2.2 is installed on about a million machines around my company, and I won't be able to upgrade them all for some time.

But you should look at both - if the standard library module does what you need, then that's one less dependency for you to worry about.

Posted by: Simon Brunning on August 28, 2003 01:01 PM

To address your other points, identity and equality are not the same thing in Python, just like in Java. But in Python, == checks for equality, and 'is' checks for identity. I think that's less awkward ;-)

One of the nicest things about Python is that you can experiment with this sort of thing interactively:

>>> import FixedPoint
>>> foo = FixedPoint.FixedPoint("1.10")
>>> bar = FixedPoint.FixedPoint("1.10")
>>> foo == bar
1
>>> foo is bar
0

So, foo and bar are equal, but since they are different objects, they are not identical.

Identity is funny in Python, though. Look at this:

>>> foo = 1
>>> bar = 1
>>> foo == bar
1
>>> foo is bar
1
>>> foo = 1234
>>> bar = 1234
>>> foo == bar
1
>>> foo is bar
0

The discrepancy here is due to the fact that Python can 'intern' objects, i.e. use a single object for all equal values. Currently, Python does this for integers up to (IIRC) 99, and all strings which look like identifiers. You can't rely on this behaviour, though - it's an implementation detail, and could change from release to release. (Not that I can think of any reason why you'd *want* to rely on it...)

Posted by: Simon Brunning on August 28, 2003 01:24 PM

To interject, the reason Python's installed on about 9 pc's in our office is just coz of SB's evangelism; Good or Bad, you decide.....

Posted by: Mark Matthews on August 28, 2003 01:41 PM

Python evangelist, and proud of it. ;-)

Posted by: Simon Brunning on August 28, 2003 05:29 PM

""" Identity is funny in Python, though. [...] The discrepancy here is due to the fact that Python can 'intern' objects, i.e. to use a single object for all equal values. Currently, Python does this for integers up to (IIRC) 99, and all strings which look like identifiers. You can't rely on this behaviour, though - it's an implementation detail, and could change from release to release. (Not that I can think of any reason why you'd *want* to rely on it...)"""

Me neither. ;-) Identity really shouldn't matter for immutable objects, should it?

Posted by: Hans on August 28, 2003 08:08 PM

Python 2.4 will contain an implementation of IBM's proposed standard for decimal arithmetic:

http://www2.hursley.ibm.com/decimal/

So far it's a pure-Python module, and can be dropped into 2.3.4. There's no other decimal module even worth a glance anymore (and I stopped looking at FixedPoint a couple years ago, to devote what time I could volunteer for this stuff to pushing the IBM standard along).

Posted by: Tim Peters on August 30, 2004 05:29 PM

To install decimal.py in 2.3.x, download the package at http://sourceforge.net/projects/sigefi.

Posted by: Facundo Batista on November 19, 2004 02:09 PM

Thabks, Facundo. Me: I'll be upgrading to 2.4 ASAP, though. ;-)

Posted by: Simon Brunning on November 19, 2004 02:20 PM

very interesting, but I don't agree with you
Idetrorce

Posted by: Idetrorce on December 15, 2007 12:53 PM
Post a comment
Name:


Email Address:


URL:



Comments:


Remember info?