printf() is not typesafe.
The arguments that you pass to printf()
are treated according to what you promise the compiler.
Also, float
s are promoted to double
s when passed through variadic arguments.
So when you promise the compiler %f
the first time (for xf
), the compiler gobbles up an entire double
(usually 8 byte) from the arguments, swallowing your float in the process. Then the second %f
cuts right into the zero mantissa of the second double.
Here's a picture of your arguments:
+-0-1-2-3-+-0-1-2-3-+-0-1-2-3-4-5-6-7-+-0-1-2-3-4-5-6-7-+
| x | x | f | f |
+---------+---------+-----------------+-----------------+
%d--------|%f----------------|%f---------------|%d------|
But f
looks like this (having been promoted to double
):
f = 3FF8000000000000
Let's draw it again with values, and speculating about your machine endianness:
| 05000000 | 05000000 | 00000000 0000F83F | 00000000 0000F83F |
| %d, OK | %f, denormal... | %f, denormal... | %d, OK |
Note that 1073217536 is 0x3FF80000.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…