My floating point number has extra digits when I print it
I define a floating point number as float transparency = 0.85f;
And in the next line, I pass it to a function -- fcn_name(transparency)
-- but it turns out that the variable transparency
has value 0.850000002
, and when I print it with the default setting, it is 0.850000002
. For the value 0.65f
, it is 0.649999998
.
How can I avoid this issue? I know floating point is just an approximation, but if I define a float with just a few decimals, how can I make sure it is not changed?
Solution 1:
Floating-point values represented in binary format do not have any specific decimal precision. Just because you read in some spec that the number can represent some fixed amount of decimal digits, it doesn't really mean much. It is just a rough conversion of the physical (and meaningful) binary precision to its much less meaningful decimal approximation.
One property of binary floating-point format is that it can only represent precisely (within the limits of its mantissa width) the numbers that can be expressed as finite sums of powers of 2 (including negative powers of 2). Numbers like 0.5
, 0.25
, 0.75
(decimal) will be represented precisely in binary floating-point format, since these numbers are either powers of 2 (2^-1
, 2^-2
) or sums thereof.
Meanwhile, such number as decimal 0.1
cannot be expressed by a finite sum of powers of 2. The representation of decimal 0.1
in floating-point binary has infinite length. This immediately means that 0.1
cannot be ever represented precisely in finite binary floating-point format. Note that 0.1
has only one decimal digit. However, this number is still not representable. This illustrates the fact that expressing floating-point precision in terms of decimal digits is not very useful.
Values like 0.85
and 0.65
from your example are also non-representable, which is why you see these values distorted after conversion to a finite binary floating-point format. Actually, you have to get used to the fact that most fractional decimal numbers you will encounter in everyday life will not be representable precisely in binary floating-point types, regardless of how large these floating-point types are.