Floating Point Imprecision in C
Floating-point arithmetic in programming involves representing real numbers using a fixed number of bits, leading to potential inaccuracies. This article addresses precision issues in C floating-point operations, exemplified by the following code:
<code class="cpp">double a = 0.3; std::cout.precision(20); std::cout << a << std::endl;
This code outputs 0.2999999999999999889 instead of the expected 0.3. Moreover, if a is added to itself 50 times, the result becomes 15.000000000000014211 instead of the expected 15.
Explanation
Floating-point numbers have limited precision, determined by their bit count. Double-precision floats have 53 bits for the fraction part, resulting in an effective precision of about 15 decimal digits.
When using std::cout.precision(20), you instruct the stream to display 20 digits of precision. However, the underlying value of a has only 15 digits of precision. The additional digits are filled with zeros, leading to inaccuracies.
The second example accumulates the inaccuracies of repeated additions. Since floating-point arithmetic is not associative, slightly different sequences of additions can yield slightly different results.
Solution
To minimize precision loss, do not set std::cout.precision higher than the available precision of the numeric type. This can be achieved using:
<code class="cpp">std::cout.precision(std::numeric_limits<double>::digits10);</code>
This limits the precision to 15 digits for double-precision floats.
However, for large numbers of repetitive calculations, accumulated errors may still occur. In such cases, alternative techniques, such as fixed-point arithmetic or using fractions with integer numerators and denominators, are recommended.
The above is the detailed content of Why Does `0.3` Become `0.2999999999999999889` in C ?. For more information, please follow other related articles on the PHP Chinese website!