I tried to test the following code, and it gave me a 434 on n, the result which I did not anticipate, what's the reason for this loss of precision?
double f = 4.35;
int n = (int) (100 * f); // n will be 434 - why?
n = (int) Math.round(100*f); // n will be 435
Floating point isn't perfect. It uses approximated values.
In particular, double
s can not represent all numbers. Just like 1/3
can't be precisely represented in decimal using a finite number of digits, so too can't 4.35
be represented in binary with a finite number of bits.
So we get rounded results. Values that are close to 4.35
, but not quite equal.
In this case, it's a bit smaller, so when you multiply it by 100, you don't get 435
, you get almost 435, which is not quite the same.
When you cast to int
, you truncate the result, so 434,999...
becomes just 434
.
In contrast, when you use Math.round
, you convert 434,999...
to exactly 435
(which can be represented precisely).
If precisely representing 4.35
is necessary, take a look at Java BigDecimal type.
Floating-point cannot represent exactly the floating-point number.
You can try printing it, you'll see that 100 * f = 434.9999999
. The int
value for that double will be 434
as it is truncating the decimal part.
The round
method will round to the closest int
number, which is 435
.