Working with Money

Figure 547. Limited float precision Slide presentation
final float result = 0.99f - 0.1f -0.1f -0.1f;
IO.println(result);
0.68999994

Figure 548. Limited double precision Slide presentation
final double result = 0.99 - 0.1 -0.1 -0.1;
IO.println(result);
0.6900000000000001

Figure 549. Using BigDecimal Slide presentation
final BigDecimal zero_dot_99 = new BigDecimal("0.99");
final BigDecimal zero_dot_1 = new BigDecimal("0.1");

BigDecimal 
  result = zero_dot_99.subtract(zero_dot_1);  // Subtracting 0.1

  result = result.subtract(zero_dot_1);       // Subtracting 0.1
  result = result.subtract(zero_dot_1);       // Subtracting 0.1

IO.println(result);
0.69

Figure 550. Chaining BigDecimal operations Slide presentation
final BigDecimal zero_dot_99 = new BigDecimal("0.99");
final BigDecimal zero_dot_1 = new BigDecimal("0.1");

BigDecimal result = zero_dot_99.
  subtract(zero_dot_1).
  subtract(zero_dot_1).
  subtract(zero_dot_1);

IO.println(result);
0.69

exercise No. 192

Chaining subtract method calls

Q:

Explain the chaining mechanism implementing three successive subtractions in Figure 550, “Chaining BigDecimal operations ”.

A:

We may re-write the statement in question:

result = zero_dot_99.subtract(zero_dot_1).subtract(zero_dot_1).subtract(zero_dot_1);
                    \               /                     /             /
                     \             /                     /             /
                      \           /                     /             /
                        0.99 - 0.1                     /             /
                                  \                   /             /
                                   \                 /             /
                                    \               /             /
                                        0.98 - 0.1               /
                                              \                 /
                                               \               /
                                                  0.97 - 0.1
                                                    == 0.96

Each subtract(...) call returns a new result instance of class BigDecimal. We can thus chain a subsequent subtract(...) call using this returned instance.

Figure 551. BigDecimal features Slide presentation
  • Higher memory allocation hosting higher precision.

  • Immutable instances

  • Calculation performance penalty.

  • Clumsy interface.


exercise No. 193

Solving factorial computational overflow

Q:

Amend the solution of Mitigating factorial overflow problems by replacing long in favour of BigInteger:

Code Result
for (int i = 20; i <= 30; i++) {
   IO.println(i + ": " + factorial(i));      
}
20: 2432902008176640000
21: 51090942171709440000
22: 1124000727777607680000
23: 25852016738884976640000
24: 620448401733239439360000
25: 15511210043330985984000000
26: 403291461126605635584000000
27: 10888869450418352160768000000
28: 304888344611713860501504000000
29: 8841761993739701954543616000000
30: 265252859812191058636308480000000

A:

/**
 * Computing factorials.
 *
 * @param value The input argument
 * @return The argument's factorial value
 */
BigInteger factorial (int value) {
    BigInteger product = BigInteger.ONE;
    while (1 < value) {
        product = product.multiply(new BigInteger(Integer.toString(value)));
        value--;
    }
    return product;
}