Re: printf("%d",float)



candy_init@xxxxxxxxx wrote:

Hi all,
I just came across the following program:

#include <stdio.h>
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", *(int *)&a);
return 0;
}

The program prints 0 and 1095237362. However, in my opinion it should
print 12 at both the places. Can anybody tell me where I am wrong?

As others have said, or tried to say, using the "%d" format specifier in
printf() does not convert the value of (a) to an int, and casting the
pointer &a to an int * does not change the value stored there into an
int. In both cases, what (usually) happens is that the bit pattern is
interpreted as an int. In other words, instead of *translating* to an
int, these cases merely point to the bit pattern of a float and *say*
that it's an int.

To convert the value of (a), you'd use something like

printf( "%d\n", ( int ) a );

This explicitly tells the compiler that you want printf() to see the int
value 12, rather than the floating-point value 12.5, and the compiler
therefore inserts code to change the bit pattern accordingly, before
printf() interprets it.

The C standard can't tell you why you got the specific values you did,
since they depend on your implementation. But we can make some pretty
safe inferences, and this might help you understand what happened.

Based on your numbers, your implementation is little-endian, it has
4-byte ints and floats and 8-byte doubles, and it uses IEEE floating-
point representation. Windows is the most common environment where
these conditions are true.

In the first case,

printf("%d\n", a);

(a) is promoted to a double, and printf() therefore receives the 8 bytes

00 00 00 00 00 00 29 40

When printf() encounters the "%d" format specifier, it looks at the next
four bytes in the argument list, because it's expecting an int to be
there. It sees 00 00 00 00, and prints "0".

In the second case,

printf("%d\n", *(int *)&a);

printf() receives the integer corresponding to the four bytes at the
address &a, which are

00 00 48 41

When interpreted as a little-endian 4-byte IEEE float, these bytes
represent the value 12.5. But when interpreted as a 4-byte int, they
represent the value you saw, 1095237632 decimal or 41480000 hex.

- Ernie http://home.comcast.net/~erniew
.



Relevant Pages

  • Re: Floating Point Approximations.
    ... (chosen as 5 decimal places based on the useful precision of the float ... int main{ ... printf; ... point for using, in certain circumstances, BCD math instead of binary ...
    (comp.databases.theory)
  • Re: Abnormal program termination
    ... foo.c:4: warning: function declaration isn't a prototype ... Your version is legal under C90 rules, but int mainis more explicit ... float ave(), average; ...
    (comp.lang.c)
  • RTF Render with Scale
    ... float fHorzSizeInches = nHorzSize / 25.4f; ... IntPtr hdc = graphics.GetHdc; ... int nHorzSize = SafeNativeMethods.GetDeviceCaps(hdc, ... PHYSICALWIDTH = 110, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: RAD vs. performance
    ... work with both int and float. ... name (e.g. "+" for both int and float addition). ... Again, it's a compatibility issue. ... contend that assuming interfaces are equivalent and inferring the most ...
    (comp.lang.misc)
  • (part1b) Han from China teaches you C
    ... int flist, mlist, slist; ... float board_size; ... static void draw_tube(float bottom_radius, float top_radius, ... glVertex3f(xmin, ymin, zmax); glVertex3f; ...
    (comp.lang.c)