Quick lessons on working with Java’s BigDecimal
Today I bring an example of the different results you can expect when using Java’s BigDecimal
class. From instantiation to applying different arithmetic operations, it is important to understand how they affect the resulting instances.
The following program shows different scenarios and results applied to BigDecimal
’s.
1package test;
2
3import java.math.BigDecimal;
4import java.math.RoundingMode;
5
6public class Test {
7
8 public static void main(String[] args) {
9 BigDecimal a = new BigDecimal("1.204165");
10 System.out.println("a (from string): " + a);
11 // 1.204165
12
13 a = new BigDecimal(1);
14 System.out.println("a (from int): " + a);
15 // 1
16
17 a = new BigDecimal(1.204165);
18 System.out.println("a (from float): " + a);
19 // 1.2041649999999999298694319804781116545200347900390625
20
21 a = a.setScale(6, RoundingMode.HALF_UP);
22 System.out.println("a (setting scale): " + a);
23 // 1.204165
24
25 System.out.println("Add (1): " + a.add(new BigDecimal("0.0001")));
26 // 1.204265
27
28 System.out.println("Add (2): " + a.add(new BigDecimal(0.0001)));
29 // 1.204265000000000000004792173602385929598312941379845142364501953125
30
31 System.out.println("Add (3): " + a.add(new BigDecimal(0.0001).setScale(6, RoundingMode.HALF_UP)));
32 // 1.204265
33
34 System.out.println("Sub (1): " + a.subtract(new BigDecimal("0.0001")));
35 // 1.204065
36
37 System.out.println("Sub (2): " + a.subtract(new BigDecimal(0.0001)));
38 // 1.204064999999999999995207826397614070401687058620154857635498046875
39
40 System.out.println("Sub (3): " + a.subtract(new BigDecimal(0.0001).setScale(6, RoundingMode.HALF_UP)));
41 // 1.204065
42
43 System.out.println("Mult (1): " + a.multiply(new BigDecimal("0.0001")));
44 // 0.0001204165
45
46 System.out.println("Mult (2): " + a.multiply(new BigDecimal(0.0001)));
47 // 0.000120416500000000005770567725917052914752503056661225855350494384765625
48
49 System.out.println("Mult (3): " + a.multiply(new BigDecimal(0.0001).setScale(6, RoundingMode.HALF_UP)));
50 // 0.000120416500
51
52 System.out.println("Mult (4): " + a.multiply(new BigDecimal(0.0001).setScale(6, RoundingMode.HALF_UP)).setScale(6, RoundingMode.HALF_UP));
53 // 0.000120
54
55 System.out.println("Mult (5): " + a.multiply(new BigDecimal(0.0001)).setScale(6, RoundingMode.HALF_UP));
56 // 0.000120
57
58 System.out.println("Div (1): " + a.divide(new BigDecimal("0.0001")));
59 // 12041.65
60
61 try {
62 System.out.println("Div (2): " + a.divide(new BigDecimal(0.0001)));
63 } catch (java.lang.ArithmeticException e) { System.out.println("Div (2): " + e.getMessage()); }
64 // Non-terminating decimal expansion; no exact representable decimal result.
65
66 System.out.println("Div (3): " + a.divide(new BigDecimal(0.0001), 6, RoundingMode.HALF_UP));
67 // 12041.650000
68
69 System.out.println("Div (4): " + a.divide(new BigDecimal(0.0001).setScale(6, RoundingMode.HALF_UP)));
70 // 12041.65
71
72 System.out.println("Div (5): " + a.divide(new BigDecimal(0.0001).setScale(6, RoundingMode.HALF_UP)).setScale(6, RoundingMode.HALF_UP));
73 // 12041.650000
74
75 try {
76 System.out.println("Div (6): " + a.divide(new BigDecimal(0.0001)).setScale(6, RoundingMode.HALF_UP));
77 } catch (java.lang.ArithmeticException e) { System.out.println("Div (6): " + e.getMessage()); }
78 // Non-terminating decimal expansion; no exact representable decimal result.
79
80 System.out.println("Abs (1): " + a.abs());
81 // 1.204165
82
83 System.out.println("Abs (2): " + a.multiply(new BigDecimal("-1.0").setScale(6, RoundingMode.HALF_UP)).setScale(6, RoundingMode.HALF_UP).abs());
84 // 1.204165
85 }
86
87}
As you can see creating an instance from a String
is the best way to get a BigDecimal
when you want to keep certain precision. Rounding and scaling play as well an important role when making calculations with BigDecimal
's.
It is worth keeping this example in mind specially in scenarios that involve currency operations, where the lack of rounding can easily generate unexpected results.