As others have stated, you should be using the %f
format to print floats, not %d
, which is for integers. There is also %e
, which prints the float in scientific notation instead of fixed notation, and there's also %g
, which prints it in either scientific or fixed, whichever is shorter.
The reason why it prints as 0 is because float arguments automatically get converted to doubles when passed as arguments to variadic functions (that is, functions which take an unspecified number of arguments) such as printf()
. The representations of the numbers 2 and 3 (the values of x
and y
) as doubles are 0x4000000000000000 and 0x4008000000000000 respectively, as calculated by the IEEE-754 Floating-Point Conversion calculator.
On little-endian machines (e.g. anything x86-based), the %d
modifier grabs the next 4 bytes off the stack and interprets them as an integer. So, when you pass the float 2, it gets converted to a double as 0x4000000000000000, which in little-endian is 00 00 00 00 00 00 00 40. The first four bytes make the integer 0, so that's what is printed out.
Note that if you printed both numbers in one statement instead of two, you would get a more surprising result:
printf("x=%d y=%d\n", x, y);
// Output: x=0 y=1073741824
Most compilers can warn you about these types of errors if you set the warning level high enough. With GCC, you should compile with the -Wformat
option (or -Wall
, which includes -Wformat
), and it will warn you when you try to print a float with %d
by accident.