What class to use for money representation?

2020-02-01 03:15发布

问题:

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?

回答1:

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 :)



回答2:

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.



回答3:

Just use decimal.



回答4:

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.



回答5:

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'


回答6:

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.