Before we see how BigDecimal class (in java) can be used to solve the floating point errors in java, we shall see what is a floating point error with an example.
What is a floating point error in java?
Floating point error is a small deviation in actual result from the expected result while evaluating an expression with floating point figures. This error definitely happens in java but I am not sure to comment on its counterparts like C++ or even C for that matter.
Now, it is time for an example to show the floating point error.
double x = 12.3d;
double y = 3.0d;
double result = x * y; //Expected 36.9. Actual = 36.900000000006
This error would happen only with double datatype in java.
What leads to floating point error ?
Computer only understands the language of binary. Any expression is fragmented to a series of addition and 2s complement with all the variables in the expression in binary format. An integer represented in binary always has finite digits. However, in the case of some( not all ! ) float point numbers, the representation may not lead to a finite digits binary format. There will be a deviation of delta from the original in the lower bits. It is only double that has enough space to accomodate the precision till the lower bits - there by leading to a float error. The error would not have occured if we had used float datatype in place of double. The float datatype does not have enough space to accomodate the lower bits that are causing the delta change from the actual. For an instance, 12.3 when represented in binary format results to a huge number. The last few digits in the lower bits are reason behind the deviation. One could obviously see the difference if the same value represented in two different formats - double & float.
The floating point is very similar to known point that 1/3 + 2/3 = 1. Evaluating the above expression with decimal figures, it would result in 0.999....(0.33... + 0.66...) which not equal to 1.
It is a usual tendancy that any java developer uses double to capture a higher precision in a applicaiton involving expressions with float point numbers. Having explained about floating point errors, one should not be surprised to see deviation of results from the actuals. However, floating point error could result in bigger surprises in a bigger applications like invoice generation.
BigDecimal to the rescue
BigDecimal is an immutable class that provides the wrapper around primitive types of number and numbers represented as String. Though BigDecimal has 16 different constructors (in Java 5), the most interesting one is the one that takes String as an argument. The internal representation of a FP number is in such a way that the actual precision is always retained. So, the above expression with BigDecimal results with no deviation.
java.math.BigDecimal x = new java.math.BigDecimal("12.3"); //rep as String
java.math.BigDecimal y = new java.math.BigDecimal("3.0");
java.math.BigDecimal result = x.multiply(y); //BigDecimal is immutable
System.out.println(result.toString()); //Expected 36.9 Actual 36.9
If time permits I would explore more on how BigDecimal is internally handling the float point numbers when represented as String (may be as floats) and share it with everyone. For the time being I just wanted to share the info about BigDecimal.
Saturday, August 9, 2008
Subscribe to:
Posts (Atom)