I''m AP above.
Also, the size of int is dependent of the Operating system not the CPU.
Yet another printf question.
I''ll try to explain better this time. I also changed the program a bit:
When calling printf, I pass it two params. One is a float value: a, the other one is the memory location of a, but as an int, not a float. a and *(int*)&a are the same memory location, and obviously, have the same 32 bits. (btw, I compiled in win32 console mode, so int is 4 bytes, as is float - I''ve double checked this).
Now from my understanding, the compiler should push both a and *(int*)&a on the stack, whether they are ints and floats. Then printf function would pop from the stack two floats with the var_arg macros (floats because of the "%f %f\n"). But because both 32 bits values pushed on the stack come from the same memory location and are identical, printf should print 0.50000 two times.
Still, I get 0.500000 0.00000.
If you still believe that there is any kind of rounding anywhere in the program:
The result is :
0.5000000
0.0000000
0.5000000
#include <stdio.h>int main(int argc, char* argv[]){ float a = 0.5f; printf ("%f %f\n", a, *(int*)&a); return 0;}
When calling printf, I pass it two params. One is a float value: a, the other one is the memory location of a, but as an int, not a float. a and *(int*)&a are the same memory location, and obviously, have the same 32 bits. (btw, I compiled in win32 console mode, so int is 4 bytes, as is float - I''ve double checked this).
Now from my understanding, the compiler should push both a and *(int*)&a on the stack, whether they are ints and floats. Then printf function would pop from the stack two floats with the var_arg macros (floats because of the "%f %f\n"). But because both 32 bits values pushed on the stack come from the same memory location and are identical, printf should print 0.50000 two times.
Still, I get 0.500000 0.00000.
If you still believe that there is any kind of rounding anywhere in the program:
#include <stdio.h>int main(int argc, char* argv[]){ float a = 0.5f; int* b = (int*)&a int c = *b; float d = *(float*)&c printf ("%f\n", a); printf ("%f\n", c); printf ("%f\n", d); return 0;}
The result is :
0.5000000
0.0000000
0.5000000
oh come on, how difficult is this to figure out? since you are explicitly casting your float type to an int, the decimal portion will be truncated, since your value is 0.5, it becomes 0. this is why c is a semi-type safe language. what you are doing doesn''t just put the same 32 bits on the stack, what you want to do is possible at the assembly language level, but c was designed so that there was *some* level of protection for the programmer.
Alright, can anyone explain why when I run the next program:
I get this output :
0.500000
0.000000
1056964608
0.500000
?
Everythink is OK except for the 0.000000 from the printf ("%f\n", c); line.
int main(int argc, char* argv[]){ float a = 0.5f; int* b = (int*)&a int c = *b; float d = *(float*)&c printf ("%f\n", a); printf ("%f\n", c); printf ("%d\n", c); printf ("%f\n", d); return 0;}
I get this output :
0.500000
0.000000
1056964608
0.500000
?
Everythink is OK except for the 0.000000 from the printf ("%f\n", c); line.
I was looking at the compiled asm, I understand what is happening.
Its pretty clear in the asm, but I'll explain anyway. printf needs to receive float's as double's, the 0.5f value is still being passed, it just not decoded because its not a double.
Edited by - burp on November 16, 2001 4:24:30 PM
Its pretty clear in the asm, but I'll explain anyway. printf needs to receive float's as double's, the 0.5f value is still being passed, it just not decoded because its not a double.
/*00401029 C7 45 FC 00 00 00 3F mov dword ptr [ebp-4],3F000000h3F000000h that's the hex value of 0.5fits being stored at [ebp-4]*/ float a = 0.5f;/*00401030 8D 45 FC lea eax,[ebp-4]address of your float00401033 89 45 F8 mov dword ptr [ebp-8],eaxits being stored at [ebp-8]*/ int *b = (int*)&a/*00401036 8B 45 F8 mov eax,dword ptr [ebp-8]loads address of float00401039 8B 08 mov ecx,dword ptr [eax]loads float0040103B 89 4D F4 mov dword ptr [ebp-0Ch],ecxits being stored at [ebp-0Ch]*/ int c = *b;/*0040103E 8B 45 F4 mov eax,dword ptr [ebp-0Ch]loads your float00401041 89 45 F0 mov dword ptr [ebp-10h],eaxits being stored at [ebp-10h]*/ float d = *(float*)&c/*00401044 D9 45 FC fld dword ptr [ebp-4]load your float00401047 83 EC 08 sub esp,80040104A DD 1C 24 fstp qword ptr [esp]stores it as double on stack0040104D 68 2C 61 42 00 push offset string "%f" (0042612c)00401052 E8 79 00 00 00 call printf (004010d0)00401057 83 C4 0C add esp,0Ch*/ printf ("%f\n", a);/*0040105A 8B 45 F4 mov eax,dword ptr [ebp-0Ch]loads your float0040105D 50 push eaxputs it on the stack0040105E 68 2C 61 42 00 push offset string "%f" (0042612c)00401063 E8 68 00 00 00 call printf (004010d0)00401068 83 C4 08 add esp,8*/ printf ("%f\n", c); //change this to printf ("%x\n", c); to see it in hex/*0040106B D9 45 F0 fld dword ptr [ebp-10h]loads your float0040106E 83 EC 08 sub esp,800401071 DD 1C 24 fstp qword ptr [esp]stores it as double on stack00401074 68 1C 60 42 00 push offset string "%d," (0042601c)00401079 E8 52 00 00 00 call printf (004010d0)0040107E 83 C4 0C add esp,0Ch*/ printf ("%f\n", d);
Edited by - burp on November 16, 2001 4:24:30 PM
Hello,
int* b = (int*)&a
It is assigning b an integer pointer with the address of a(float) which is converted to an int pointer. (Fine)
b is an int pointer to a floats value
Then
printf ("%f %f\n", a, *b);
displays a correctly
*b displays the value stored in a(but only the number of bytes that an int uses) as that int value converted to a float value
int* b = (int*)&a
It is assigning b an integer pointer with the address of a(float) which is converted to an int pointer. (Fine)
b is an int pointer to a floats value
Then
printf ("%f %f\n", a, *b);
displays a correctly
*b displays the value stored in a(but only the number of bytes that an int uses) as that int value converted to a float value
1056964608 == 0x3f000000 == 0.5f;
double(0.5f) == 0x3fe0000000000000 == 4602678819172646912
Edited by - burp on November 16, 2001 5:43:15 AM
double(0.5f) == 0x3fe0000000000000 == 4602678819172646912
Edited by - burp on November 16, 2001 5:43:15 AM
Thanks burp, you are right. I still don''t understand how come passing a float as an argument can result in a double being pushed on the stack. Seems to me like a bug of VC.
quote:Original post by Diodor
Thanks burp, you are right. I still don''t understand how come passing a float as an argument can result in a double being pushed on the stack. Seems to me like a bug of VC.
No, you just don''t understand casting and C''s typing yet. Give it time.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement