What class should I use for representation of money to avoid most rounding errors?
Should I use Decimal
, or a simple built-in number
?
Is there any existing Money
class with support for currency conversion that I could use?
Any pitfalls that I should avoid?
I assume that you talking about Python.
http://code.google.com/p/python-money/
"Primitives for working with money and currencies in Python" - the title is self explanatory :)
Never use a floating point number to represent money. Floating numbers do not represent numbers in decimal notation accurately. You would end with a nightmare of compound rounding errors, and unable to reliably convert between currencies. See Martin Fowler's short essay on the subject.
If you decide to write your own class, I recommend basing it on the decimal data type.
I don't think python-money is a good option, because it wasn't maintained for quite some time and its source code has some strange and useless code, and exchanging currencies is simply broken.
Try py-moneyed. It's an improvement over python-money.
You might be interested in QuantLib for working with finance.
It has built in classes for handling currency types and claims 4 years of active development.
You could have a look at this library: python-money. Since I've no experience with it I cannot comment on its usefullness.
A 'trick' you could employ to handle currency as integers:
- Multiply by 100 / Divide by 100 (e.g. $100,25 -> 10025) to have a representation in 'cents'
Simple, light-weight, yet extensible idea:
class Money():
def __init__(self, value):
# internally use Decimal or cents as long
self._cents = long(0)
# Now parse 'value' as needed e.g. locale-specific user-entered string, cents, Money, etc.
# Decimal helps in conversion
def as_my_app_specific_protocol(self):
# some application-specific representation
def __str__(self):
# user-friendly form, locale specific if needed
# rich comparison and basic arithmetics
def __lt__(self, other):
return self._cents < Money(other)._cents
def __add__(self, other):
return Money(self._cents + Money(other)._cents)
You can:
- Implement only what you need in your application.
- Extend it as you grow.
- Change internal representation and implementation as needed.