Printing int as float in C
I'm using Visual Studio TC compiler for Little Endian. The following is the piece of code:
void main()
{
float c = 1.0;
int a = 0x3F800000;
int *ptr = (int *)&c;
printf("n0x%Xn", *ptr);
printf("na = %f", a);
printf("nc = %f", c);
return;
}
The output is:
0x3F800000
a = 0.000000
c = 1.000000
Float value 1.0 is 0x3F800000 and stored as 00 00 80 3F in memory for Little Endian. The same value is assigned to int a. How printf prints 0.000000 for int a while 1.000000 for float c? I've seen it prints all integer values as 0.000000, when printed using %f in printf.
Also, since printf is variable argument function, how does it knows whether the passed value in the register is int or float?
My psychic powers tell me Adam Liss's comment is the right answer: float
arguments are promoted to double
, so the printf()
function expects that to happen: It expects a 64-bit value on the stack, but gets 32 bits plus garbage data that happen to be zero.
If you increase the display precision, the display should be something like a = 0.00000000001
.
This also means this should work:
void main()
{
double c = 1.0;
long long a = 0x3FF0000000000000;
long long *ptr = (long long *)&c;
printf("n0x%llXn", *ptr);
printf("na = %f", a);
printf("nc = %f", c);
return;
}
I have compiled your code in gcc and the code generated is following:
movl $0x3f800000, %eax
movl %eax, -4(%ebp)
movl $1065353216, -8(%ebp)
leal -4(%ebp), %eax
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl $LC1, (%esp)
call _printf
movl -8(%ebp), %eax
movl %eax, 4(%esp)
movl $LC2, (%esp)
call _printf
flds -4(%ebp)
fstpl 4(%esp)
movl $LC3, (%esp)
call _printf
This could give you a hint, that float parameters are not taken from the regular stack but rather from the stack of floating points... I would expect that there would be something random rather than 0...
As -Wall
states: warning: format '%f' expects type 'double', but argument 2 has type 'int'
. This is undefined behavior as also explained in more detail here.
If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding coversion specification, the behavior is undefined.
So what you see here, is what the compiler builder decided to happen, which can be anything.
链接地址: http://www.djcxy.com/p/90300.html上一篇: 赋值和printf之间的舍入不同
下一篇: 在C中将int打印为float