Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When can I use floating-point types in Java to do monetary calculations?

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?

like image 506
Michael Avatar asked Dec 11 '22 23:12

Michael


1 Answers

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.

like image 93
Eric Postpischil Avatar answered Dec 28 '22 23:12

Eric Postpischil