Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending BigDecimal?

I've a fair bit of code using BigDecimal Class and I hate the clumsiness of the interface.

I've alleviated the pain of using BigDecimals with integers by creating a helper class with static methods with the following methods:

compare(BigDecimal first, int second)
divide(BigDecimal dividend, BigDecimal divisor, int scale)
divide(BigDecimal dividend, int divisor, int scale)
divide(int divident, int divisor, int scale)
multiply(BigDecimal first, BigDecimal second, int scale)
multiply(BigDecimal first, int second, int scale)
multiply(int first, int second, int scale)
zeroPad(BigDecimal value, int totalLength, int scale)

That's all I need for now and the code is a little more readable than before. However, I read that static methods are a "bad" thing and that they don't follow OO-principles.

If I extend BigDecimal however, I'd define a new type and thus I'd have to re-define all methods to wrap them with my object or I won't be able to use the results with the augmented methods. It doesn't seem a smart thing to do.

How would you approach this problem?

like image 775
stivlo Avatar asked Jun 25 '11 09:06

stivlo


1 Answers

I would do it exactly as you have!

All design decisions of this type must be based on a wish to make the code more maintainable for the next programmer that will take over the code after you. Which is why we make O-O design and component based development in the first place.

But given the syntax of Java, it is really difficult to make an API for math-based expressions. I have two problems with the current BigInteger API:

  • it is not very close to the usual math-notation
  • it is asymmetric for symmetric operators like add and multiply

[Operator-overload is one of the few features of C++, I miss in Java]

Which is more readable?

BigInteger a = ...;
BigInteger b = ...;
BigInteger c = divide(a, b);

or

BigInteger a = ...;
BigInteger b = ...;
BigInteger c = a.divide(b);

Personally, I prefer the second version.

Worse is the cases where numbers of different base types are part of the same expression. E.g.

int a = ...;
BigInteger b = ...;
BigInteger c = divide(a, b);

or

int a = ...;
BigInteger b = ...;
BigInteger c = BigInteger.valueOf(a).divide(b);

Also consider the big differences in the notations from the small changes in the corresponding math notation:

  • (a-b)*c is translated to a.subtract(b).multiply(c) or multiply(subtract(a,b),c)
  • c*(a-b) is translated to c.multiply(a.subtract(b)) or multiply(c,subtract(a,b))

For me, it is easier to write and read the static method notation, than the "pure" O-O based notation.

like image 192
Tonny Madsen Avatar answered Oct 27 '22 01:10

Tonny Madsen