Skip to content

Money-is-Money v0.16

Putting money-is-money into my own Maven repository gave the impetus to me to clean up the actual code base of the library. There are now a grand total of three classes, including an interface, which is much reduced. As anyone who knows me, will know that I think this is a great improvement. See this post - also linked in the first sentence above – to learn the details of the Maven repository and how and where to get the source code check out.

You can manually browse the artefacts in the repository here.

Here’s the updated README:

This package is copyright 2008-2009 Scot Mcphee.

Email: scot.mcphee at gmail.com

Licence is the M.I.T. Licence. Please see the file “LICENCE”.

WHAT IS Money-Is-Money?

Money-Is-Money is a library for the correct manipulation of monetary data. I wrote this small library because I found that there were not any available public source Money implementations, despite some Time-based libraries promising such (I guess Time is more interesting to programmers than filthy lucre).

It consists primarily of an interface, called ‘Money’, and a Factory for making money, called ‘MoneyMaker’. There is a single implementation classes, MoneyAmount.

Money uses BigDecimal throughout to represent values. Yes, that’s a java.math.BigDecimal. If you whine about wanting to use doubles and floats congratulations! You are the target audience and therefore you should *really* be using this library and I won’t go into debate here why it’s wrong to use floating point logic in Money implementations.

Money is designed to be an immutable object. All operations on Money, such as Money.add(Money) returns a new instance of Money representing the added amounts. There are operations for add, subtract, divide, and multiply. The default rounding mode is HALF_EVEN or ‘bankers rounding’. If a value comes out to 0.5, it is rounded to the EVEN value, so $3.555 at a precision of 2 decimal places becomes 3.56, and so does $3.565. Divide and multiply also include methods to perform those operations with a user-specified rounding mode. There are also methods to do high-precision “no rounding” division and multiplication (dividePrecise and multiplyPrecise), which will throw an ArithmeticException if the decimals cannot be terminated and therefore have no decimal representation, e.g. 10/3, so be careful in using it.

There is also two methods to ‘proRate’ money. The first takes the existing money and divides it up as equally as possible into the number of buckets you specify, with the modulo distributed in as small as increments as possible across as many of the buckets as possible.

This is NOT THE SAME as dividing by the number you specify. So $10.00 divided into 3 buckets results in buckets containing $3.34, $3.33, $3.33. The specification is that adding the buckets back up should always result in the original amount without any rounding errors. You should be able to pro rate an amount, then pro rate those amounts, recursively many many times and adding up all the ‘leaf’ values will result in EXACTLY the original amount.

There is an additional method of ‘proRate’. That is the weighted pro-rate, proRateWeighted. It allows you divide a money amount into a number of buckets with each amount weighted according to a value in an array. E.g. an array of {1, 2} divides the amount into 2 buckets, the first one having 1/3 of the amount, the second 2/3. This can get much more complex than that simple example, e.g. consider $54 divided by the weights {1, 1, 2, 3, 5, 8, 13, 21}. Well in that case I am cheating because the amounts returned would be {1, 1, 2, 3, 5, 8, 13, 21}, but consider some random amount, let’s say $9824516.53 divided by that same array of weightings. The weightings have to be obeyed and the numbers must all add up at the end. This implementation was supplied by my friend and former colleague Tim Eagles and refined a little by myself.

The current implementations of both the ‘proRate’ methods take the remainder R and distribute it amongst the *first* R elements of the (weighted or un-weighted) buckets. Thus, the earliest elements may be out by 1 cent (or 1 whole Yen) compared to a straight floating point division of value divided by number of buckets.

If you find this library at all useful, or have improvements and suggestions, drop me a line at scot.mcphee@gmail.com

Please remember to shake your MoneyMaker.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • DZone
  • StumbleUpon
  • Technorati
  • TwitThis
  • LinkedIn

3 Comments

  1. Ben wrote:

    That’s some tidy code — good to see use of AbstractMoney as a class name too :-)

    Saturday, April 18, 2009 at 13:53 | Permalink
  2. Scot Mcphee wrote:

    AbstractMoney deleted in 0.16 !!! There is just interface Money and class MoneyAmount.

    Version 0.17 will implement ImaginaryMoney, which as you know, because money is the root of all evil, and evil is negative, and the root of a negative number is imaginary.

    Saturday, April 18, 2009 at 14:32 | Permalink
  3. Ben wrote:

    talk about contrived meaning :-)

    Monday, April 20, 2009 at 22:32 | Permalink