Decimal class - rounding behavior; static init method

Skip to first unread message

John O'Hanley

Sep 24, 2013, 6:18:47 PM9/24/13

I think the Decimal class has 2 defects that should be fixed:

1. It has too much policy with respect to rounding. A calc can often proceed in steps, with intermediate values; in such cases, the rounding should only be done at the end of the calc. With the current Decimal class, the rounding will often occur at each intermediate step. That's probably not what it should be doing. (The BigDecimal class itself allows for such calcs, without any behind-the-scenes rounding policy.)

Example of one place in the current code:
  public Decimal times(Decimal aFactor){
    BigDecimal newAmount = fAmount.multiply(aFactor.getAmount());
    newAmount = newAmount.setScale(fTimesDivDecimals, ROUNDING);
    return  new Decimal(newAmount);

For the above example, the proposed change is simply to take out the rounding:
  public Decimal times(Decimal aFactor){
    BigDecimal newAmount = fAmount.multiply(aFactor.getAmount());
    return  new Decimal(newAmount);

2. The static init method makes me unhappy. Past experience with static, mutable data in general has left me with really bad feelings. This init method now looks like a naive way of doing things.

What I'm proposing is to match the Decimal class closely to this alternate impl:

The proposed change would remove these 5 methods, and break any code that calls them:

The above methods talk to the data that does the internal rounding.

More subtly, any callers that have 'times' or 'div' calls will need to check to see if the result still has the desired number of decimals. If not, their code will simply need to add a call to a 'round' method. Such rounding issues will usually be obvious during system testing.

The above changes to callers aren't small. But, in my opinion, they would be a marked improvement to the design of the Decimal class.

The proposed changes would also:
- add a number of simple overloads for double and long, for hard-coded data; (the doubles and longs  would get internally converted immediately to a Decimal)
- a few new methods: pow, isInteger, from, round
- some more convenience constants

What do you think about these ideas? Agree, disagree?

- John

Reply all
Reply to author
0 new messages