Microsoft KB Archive/44816

= 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</li></ul>

 Microsoft Visual C++ 1.0 Professional Edition</li></ul>

 Microsoft Visual C++ 2.0 Professional Edition</li></ul>

 Microsoft Visual C++ 2.1</li></ul>

 Microsoft Visual C++ 4.0 Standard Edition</li></ul>

 Microsoft Visual C++ 5.0 Standard Edition</li></ul>

 Microsoft Visual C++ 6.0 Service Pack 5</li></ul> </li></ul>

-

<div class="notice_section">

This article was previously published under Q44816

<div class="summary_section">

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 &quot;%x&quot; and &quot;%lx&quot; with &quot;%lx %lx&quot;.

Sample Code
/* Compile options needed: none

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

printf(&quot;\nFLOAT        %x   %e&quot;, flt,flt); printf(&quot;\nDOUBLE       %lx  %le&quot;,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(&quot;\nFloat %lx %lx %e&quot;,flt,flt); printf(&quot;\nDouble %lx %lx %le&quot;,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

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.