A simple code like this printf("hex representation for %f is [%a]\n", 3.14, 3.14);
, I expect the result to be 0x4048f5c3
(full binary version is: 0100 0000 0100 1000 1111 0101 1100 0011
, 0x4.8f5c3p-1
) according to reference websites below, but the compiled executable shows [0xc.8f5c3p-2]
(binary: 1100.1000 1111 0101 1100 0011
), why did the C compiler shows exponent as -2 instead of -1?
The compiler setting is:
"command": "c:/msys64/mingw64/bin/gcc.exe",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe",
"-Wall",
"-Werror",
"-std=c11"
Reference: https://users.cs.fiu.edu/~downeyt/cop2400/float.htm https://gregstoll.com/~gregstoll/floattohex/
CodePudding user response:
The website you are using is displaying the binary representation of a floating-point number. For example, 3.14
is 40 48 F5 C3
in big-endian, or C3 F5 48 40
in little-endian.
The hex representation in C is the actual floating-point number in base 16, not it's binary representation. 0xc.8f5c3p-2
means c.8f5c3 * 2^(-2)
. If we convert this to decimal using the usual conversion algorithm, we get 3.14
:
12(C) * 16^0 8 * 16^(-1) 15(F) * 16^(-2) 5 * 16^(-3) 12(C) * 16^(-4) 3 * 16^(-5) = 12 0.5 0.05859 ... = 12.56
(with approximation)
Now multiply by 2^(-2)
, or divide by 4
, and we get 3.14
.
The difference between the 2 representations is shown here (note that this program technically causes undefined behavior in C, because of the uint32_t*
to float*
cast followed by dereference, but in this case the behavior is to use the binary representation to create a floating-point number, as one would expect):
#include <stdio.h>
#include <inttypes.h>
// Assuming IEE-754 representation of 32-bit floats
int main(void)
{
float x = 0xC.8F5C3p-2;
uint32_t y = 0x4048F5C3;
printf("Base-16 representation of %f is: %A\n", x, x);
printf("Binary representation of %f is: 0X%"PRIX32"\n", *(float*)&y, y);
}
And this is the output I get on my computer:
Base-16 representation of 3.140000 is: 0XC.8F5C3P-2
Binary representation of 3.140000 is: 0X4048F5C3