[37] in Athena Bugs

home help back first fref pref prev next nref lref last post

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):





home help back first fref pref prev next nref lref last post