[JAVA] Do not use floats and doubles to calculate decimal numbers

Let's take a note of the parts that were traversed during the development of Accounting Sirth Japan. I used to outsource development overseas, and there was a part where I calculated using floats and doubles easily, and it was a story when I corrected it myself.

Float and double are prohibited for decimal calculation of amount

Basically, binary floating point types such as float and double should not be used in monetary calculations. why? It is exactly in decimal point calculation Because it can't be calculated.

What does that mean

float a = 1.03;
float b = 0.42;

System.out.println(a-b)
0.6100000000000001

It will be. I can't give you the exact amount ...

Use Big Decimal to calculate decimal numbers

Use Big Decimal if you want to calculate the amount accurately.

import java.math.BigDecimal

BigDecimal a = new BigDecimal("1.03");
BigDecimal b = new BigDecimal("0.42");

BigDecimal c = a.subtract(b);
System.out.println(c.toString());
0.61

BigDecimal cannot be described with a calculation code, so it is hard to see anyway, and it seems to be annoying.

Big Decimal Trap

There is a trap if it is okay to use Big Decimal here. If you make a mistake in the initial assignment in BigDecimal, it will be meaningless even though you are trying to calculate accurately in BigDecimal. What this means is that when you substitute a decimal, you shouldn't substitute it numerically. You have to substitute it with letters.

BigDecimal rate1 = new BigDecimal("0.1");
BigDecimal rate2 = new BigDecimal(0.1);

This is the difference The former can be calculated accurately because it is passed as a string argument. The latter is a trap where 0.1 flows to the constructor of the double argument, so it is treated as a binary floating point number and then assigned! I don't need the double argument constructor itself, I want it to be a compile error.

Finally

I was using floats and doubles everywhere for outsourcing, and it was troublesome to fix it. I was scared. It is easy to program in the ratio calculation and coordinate calculation of the screen configuration that does not require perfect accuracy, so it is easy to use double or float, but for those who build a system that handles money, "double for money" It is a common sense that you should know "float is prohibited" from the beginning. I'll cry for 1 yen later.

We have stopped such offshore and made it completely in-house, and we are currently looking for friends to make the system together.

Recommended Posts

Do not use floats and doubles to calculate decimal numbers
Ruby's "1101" .to_i (2) does not convert decimal numbers to decimal numbers.
How to use Big Decimal
In order not to confuse the understanding of getters and setters, [Do not use accessors for anything! ]
How to use StringBurrer and Arrays.toString.
How to use EventBus3 and ThreadMode
[Java] Do not use "+" in append!
How to use equality and equality (how to use equals)
How to use OrientJS and OrientDB together
Do not use instance variables in partial
How to set up and use kapt
[Rails] [Memo] When to add = to <%%> and when not
How to use substring and substr methods
How to use @Builder and @NoArgsConstructor together
[Ruby] Learn how to use odd? Even? And count the even and odd numbers in the array!
Do not issue parameters to POST request and URL from Form with Wicket