Microsoft KB Archive/44816

From BetaArchive Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Knowledge Base


PRB: printf() Appears to Print Incorrect Results for Floats

Article ID: 44816

Article Last Modified on 12/12/2003



APPLIES TO

  • The C Run-Time (CRT), when used with:
    • Microsoft Visual C++ 1.0 Professional Edition
    • Microsoft Visual C++ 1.5 Professional Edition
    • Microsoft Visual C++ 1.51
    • Microsoft Visual C++ 1.52 Professional Edition
    • Microsoft Visual C++ 1.0 Professional Edition
    • Microsoft Visual C++ 2.0 Professional Edition
    • Microsoft Visual C++ 2.1
    • Microsoft Visual C++ 4.0 Standard Edition
    • Microsoft Visual C++ 5.0 Standard Edition
    • Microsoft Visual C++ 6.0 Service Pack 5



This article was previously published under Q44816

SUMMARY

The printf() in the sample code below does not print out the correct values; the float is printed with a hexadecimal specifier before the float specifier. The problem is that a 2-byte format specifier is being used for an 8-byte value. To correct this problem, replace "%x" and "%lx" with "%lx %lx".

Sample Code

/* Compile options needed: none
*/ 

#include <stdio.h>
main()
{
   float flt  = 1.701411e+038;
   double dbl = 1.701411e+038;

   printf("\nFLOAT         %x   %e", flt,flt);
   printf("\nDOUBLE        %lx  %le",dbl,dbl);
}

The above code produces incorrect output. However, the source code is incorrect. When printing, the above code is using a 2-byte hex format specifier %x or a 4-byte hex format specifier %lx with an 8-byte double argument (the float is also passed as a double). This produces the incorrect results. To solve this problem, use two %lx format specifiers to remove 8-bytes off the stack before printing the second double. For example:

printf("\nFloat  %lx %lx %e",flt,flt);
printf("\nDouble %lx %lx %le",dbl,dbl);

This works correctly for Microsoft C under MS-DOS or OS/2; however, this code may not be portable under other systems that support types of different sizes.

Eight bytes are passed, independent of the fact that one argument is a float and the other a double, because the float is being promoted to a double. This is because all floats are passed as doubles unless they are specified as floats in the prototype. Because printf() has a variable number of parameters, the arguments are not prototyped and therefore all floats are promoted up to doubles.

Keywords: kbcrt kbprb KB44816