[37] in Athena Bugs
A bug with printf, sprintf, fprintf
daemon@ATHENA.MIT.EDU (jhslater@ATHENA.MIT.EDU)
Mon Mar 14 17:11:50 1988
From: <jhslater@ATHENA.MIT.EDU>
To: bugs@ATHENA.MIT.EDU
Cc: geer@ATHENA.MIT.EDU, yba@ATHENA.MIT.EDU, hconsult@ATHENA.MIT.EDU
Date: Mon, 14 Mar 88 16:47:57 EST
Program with which you had the problem:A C program
Name of person who discovered the bug:jhslater
Their MIT phone number:x3-7134
Their MIT address:1-270
Their Athena Login ID:jhslater
Name of consultant reporting bug:
------------------------------------------------------------------------
A brief synopsis of the problem:
If formatted output is used to print double values which are very
close to 1.0, 10.0, 100.0, etc., certain formats cause the values to
print as 0.00000 instead of the appropriately rounded value.
eg 0.9999999 prints as 0.000000 in a %lf field instead of 1.0
The same thing occurs in exponential formats if the number of
significant digits is less than the number of 9's. Many numerical
evaluations result in values 'close to' 1.0 or 10.0 but not exactly
there.. For example sin(1.5698) prints as 0.000000 in %lf instead of
1.000000 although sin(1.5697) does not. Of course, sin() is declared
as double sin(); in the calling procedure.
------------------------------------------------------------------------
Please describe the problem in detail (mention any necessary files or
commands that may be involved, on which machine the bug happened, and what
the program did that was wrong):
Attached is a short example with a long comment.
/***************************************************************************
Test program illustrating a bug in printf for values very close to
1.0, 10.0, 100.0
Author: John H. Slater jhslater March 14, 1988
Input the following values for x
9.9999e-01
9.99999e-01
9.999999e-01
The %lf format fails to round 9.999999e-01 up to 1.00000, and
prints it as 0.000000. The same error occurs in exponential format
when the number of significant digits exceeds the number specified.
Oddly enough, %.3f works!
This problem also occurs if we approach 10.0 from below with
9.9999e+00
9.99999e+00
9.999999e+00
In this case %.3f prints as 0.000, but %lf prints as 10.000000.
It also occurs if we approach 100.00 from below with
9.9999e+01
9.99999e+01
9.999999e+01
In this case %.5e prints out as 0.00000e+01 instead of 1.00000e+02
This disturbing bug also manifests itself in sprintf (and of course fprintf).
The input using exponential notation is not the problem, as
0.999999 9.999999 99.999999 cause the same errors!
The bug was discovered by a 1.00 student who was evaluating sine(x) by series
summation. sine(1.5698) prints out as 0.000000 instead of 1.000000,
since the series converges to 9.9999950367e-01.
The mathlib sin(x) also evalutes sin(1.5698) and prints it out as
0.000000 viz
double sin();
printf("%lf %20.3e", sin(1.5698), sin(1.5698));
THIS IS A VERY REAL PROBLEM which may often lead to 'wrong' answers
being printf() 'ed or especially sprintf() 'ed into character strings
for XText() interactive displays, when limited significant digits are
required
****************************************************************************/
main()
{
double x;
for(;;) {
printf("Input floating number. (-999.0 to quit) -> ");
scanf("%lf", &x);
if(x == -999.0)
break;
printf("(%%lf) %lf (%%.3f) %.3f (%%13.5e) %13.5e (%%17.10e) %17.10e\n",
x, x, x, x);
}
printf("-999.0 read. Exiting...\n");
}
------------------------------------------------------------------------
Repeat by (please enter a set of commands which will allow us to
repeat the bug):
------------------------------------------------------------------------
Fix (if you know what it is):