I learned I cannot use floating-point types (float
/double
in Java) to do money calculations (and any other calculations when I need precise results). I have to use decimal
number types (BigDecimal
in Java) instead.
Now I wounder when I can use the floating-point types. Do they provide any precision guarantee ? Suppose I would like to calculate some formula with precision 0.001
. How do I know if I can use floating-point types for this calculation or not?
You can use floating-point types in Java, or other languages, when you can demonstrate the results are acceptable for your application.
Using BigDecimal does not solve this problem, by itself. For example, suppose a bank account contains $87.34, and you must add interest for one month given an annual percentage rate of 2.37%. First, BigDecimal will not calculate the monthly interest rate correctly, because you must divide 2.37% by 12, and 2.37/12 (or .0237/12) is not exactly representable in decimal. Second, even if BigDecimal did calculate the monthly interest rate correctly, and calculated the interest on $87.34 correctly, you probably still need to round that amount to some number of cents before adding it to the balance. The rules for that rounding may be specified in some legal document and might not match how BigDecimal does rounding.
Both decimal floating-point and binary floating-point are capable of calculating many results precisely, much more precisely than the .001 precision you suggest in your example. Both are also capable of producing significant errors when used in various ways.
Therefore, to use floating-point, you must understand what values the types can represent, what errors occur in floating-point operations, what operations you will perform, and what your application requires. Often, it is possible to avoid floating-point errors by crafting operations carefully. For example, you can work with currencies by scaling amounts to integer values (use 8734 to represent $87.34 instead of using 87.34 to represent 87.34). As another example, you can demonstrate that the accumulated error from several operations is less than half a cent, and therefore you can perform the operations and round the final result to the nearest cent, and that will be correct because the error was never large enough to make the final answer incorrect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With