Java: Fix floating point math
Friday, March 5th, 2021I was working on my Android app skills and was creating a simple calculator. It was very basic and worked great until I started to play with division. I thought, this will be easy. Just type, 3 / 2 = and I would be given the answer. We all know the answer is, of course, 1.49999998.
Wait a minute! Why would this be the answer you ask? This has to do with the data type used and if you are doing calculations where the result really matters such as for money, then you should not be using a double or a float type.
BigDecimal to the rescue. The BigDecimal type “fixes” the issues that come up when you are using decimal numbers and stop the precision loss. This means that the 3 / 2 = will indeed give you 1.5. But you need to use the BigDecimal functions to add, subtract, multiply and divide. Not just the ‘+’ (plus), ‘-‘ (minus), ‘*’ (multiply), ‘/’ (divide) operators.
Instead of using doubles, like this:
double firstNumber = 3;
double secondNumber = 2;
You should use BigDecimal, like this:
BigDecimal firstNumber = new BigDecimal(3);
BigDecimal secondNumber = new BigDecimal(2);
But now when you try to add, subtract, multiply or divide using a the traditional operators, it no longer works. You will need to replace them with the methods named after the operations you are attempting.
// Add
double addResult = firstNumber + secondNumber; //error
BigDecimal addResultBd = firstNumber.add(secondNumber);
// Subtract
double subtractResult = firstNumber - secondNumber; //error
BigDecimal subtractResultBd = firstNumber.subtract(secondNumber);
// Multiply
double multiplyResult = firstNumber * secondNumber; //error
BigDecimal multiplyResultBd = firstNumber.multiply(secondNumber);
// Divide
double divideResult = firstNumber / secondNumber; //error
BigDecimal divideResultBd = firstNumber.divide(secondNumber);
So using BigDecimal can save your sanity when your calculations are critical to what you are expecting. Calculators that give you a “close enough” representation of the numbers you are expecting are not very good.