Consider this program
int main()
{
float f = 11.22;
double d = 44.55;
int i,j;
i = f; //cast float to int
j = d; //cast double to int
printf("i = %d, j = %d, f = %d, d = %d", i,j,f,d);
//This prints the following:
// i = 11, j = 44, f = -536870912, d = 1076261027
return 0;
}
Can someone explain why the casting from double/float to int works correctly in the first case, and does not work when done in printf?
This program was compiled on gcc-4.1.2 on 32-bit linux machine.
EDIT: Zach's answer seems logical, i.e. use of format specifiers to figure out what to pop off the stack. However then consider this follow up question:
int main()
{
char c = 'd'; // sizeof c is 1, however sizeof character literal
// 'd' is equal to sizeof(int) in ANSI C
printf("lit = %c, lit = %d , c = %c, c = %d", 'd', 'd', c, c);
//this prints: lit = d, lit = 100 , c = d, c = 100
//how does printf here pop off the right number of bytes even when
//the size represented by format specifiers doesn't actually match
//the size of the passed arguments(char(1 byte) & char_literal(4 bytes))
return 0;
}
How does this work?
"%f" is the (or at least one) correct format for a double. There is no format for a float , because if you attempt to pass a float to printf , it'll be promoted to double before printf receives it1.
A float value can be converted to an int value no larger than the input by using the math. floor() function, whereas it can also be converted to an int value which is the smallest integer greater than the input using math. ceil() function. The math module is to be imported in order to use these methods.
Since a float is bigger than int, you can convert a float to an int by simply down-casting it e.g. (int) 4.0f will give you integer 4. By the way, you must remember that typecasting just get rid of anything after the decimal point, they don't perform any rounding or flooring operation on the value.
Example. float x=1.9,y=2.4; int a,b; a = (int)(x+0.5); b = (int)(y+0.5); now you get correct answers, a has 2.
There's no such thing as "casting to int
in printf
". printf
does not do and cannot do any casting. Inconsistent format specifier leads to undefined behavior.
In practice printf
simply receives the raw data and reinterprets it as the type implied by the format specifier. If you pass it a double
value and specify an int
format specifier (like %d
), printf
will take that double
value and blindly reinterpret it an an int
. The results will be completely unpredictable (which is why doing this formally causes undefined behavior in C).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With