I'm trying to implement printf
and I want to know how printf
rounds floating-point numbers because I cannot find a general rule
If for example input => printf("|%.f| |%.1f| |%.2f| |%.5f| |%.12f", 0.000099, 0.000099, 0.000099, 0.000099, 0.000099);
Here is the output => |0| |0.0| |0.00| |0.00010| |0.000099000000
|0| |0.0| |0.00| |0.00010| |0.000099000000
I use the method from IEEE-754 so our floating-point number in memory is: 0.000098999999999999994037755413067714016506215557456016540527343750
My question is when and how should I round my floating-point number?
I am looking for a general rule that I must follow for all floating-point numbers.
Not sure if this is exactly how printf
does it, but this seems to work for your example:
Add 5/(10^(number of decimal points+1). Then truncate.
Your interpretation is flawed: Your C compiler is upcasting your constants to doubles. So it's not using 0.0000989999....
It's using the more accurate double equivalent.
Try this:
printf("|%.f| |%.1f| |%.2f| |%.5f| |%.12f", (float)0.000099, (float)0.000099, (float)0.000099, (float)0.000099, (float)0.000099);
Output:
|0| |0.0| |0.00| |0.00010| |0.000098999997
The problem you are trying to address is actually very difficult to solve correctly.
Many existing printf
implementations use conversion code dtoa.c written by David M. Gay almost 30 years ago.
You can learn more about this from this question, which is not an exact duplicate:
And these sites:
The C standard provides the following in §7.21.6.1p13:
For
e, E, f, F, g, and G
conversions, if the number of significant decimal digits is at mostDECIMAL_DIG
, then the result should be correctly rounded. If the number of significant decimal digits is more thanDECIMAL_DIG
but the source value is exactly representable withDECIMAL_DIG
digits, then the result should be an exact representation with trailing zeros. Otherwise, the source value is bounded by two adjacent decimal stringsL<U
, both havingDECIMAL_DIG
significant digits; the value of the resultant decimal stringD
should satisfyL ≤ D ≤ U
, with the extra stipulation that the error should have a correct sign for the current rounding direction.
However, that paragraph is part of a subsection headed "Recommended Practice". (If Annex F is in effect, then the recommended practice is required. See F.5.)
"Correctly rounded" is defined by the current rounding direction. See fsetround
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.