I know the problem of doubles due to base 2 calculations:
var total: Double = 0.1
total *= 0.1
total /= 0.1
println(total) // 0.10000000000000002
I understand that BigDecimal should be used for money related calculations, but in my case the little precision loss is acceptable, cuase all the currency calculation I need to do is convert currency C1 to currency C2 and back to currency C1. The only thing is that the two values of C1 after this conversion should match, when I show the result to customer with 5 decimal precision.
Now I'm trying to figure out, how much the value might drift over this conversion at worst case scenario? What are the numbers that might cause the worst case scenario?
You could read the description of double-precision floating-point:
The 11 bit width of the exponent allows the representation of numbers with a decimal exponent between 10^−308 and 10^308, with full 15–17 decimal digits precision.
Since you want 5 fraction digits, that means you're ok up to max. 10 integral digits.
Or you could test it. Sometimes empirical evidence is more convincing:
double value = 0.00009;
while (true) {
String nextDown = String.format("%.5f", Math.nextDown(value));
String nextUp = String.format("%.5f", Math.nextUp(value));
if (! nextDown.equals(nextUp))
break; // loss of precision to 5 decimals
System.out.printf("Good: %.5f%n", value);
value = value * 10 + 0.00009;
}
System.out.printf("Bad: %.5f%n", value);
Output
Good: 0.00009
Good: 0.00099
Good: 0.00999
Good: 0.09999
Good: 0.99999
Good: 9.99999
Good: 99.99999
Good: 999.99999
Good: 9999.99999
Good: 99999.99999
Good: 999999.99999
Good: 9999999.99999
Good: 99999999.99999
Good: 999999999.99999
Good: 9999999999.99999
Bad: 99999999999.99997
Yup, 10 is good, 11 bad.