As you may know, standard IEEE 754 defines the format of floating point representation. I came across with this IEEE 754 Converter that shows you how a certain value will be represented on this format in binary and hex.
So, for example, let's test 3.1416:
So, I was wondering how we can get this hex representation in my machine;
Let's figure out!
First, I declare a float variable and print it:
#include <stdio.h> main() { float pi = (float) 3.1416; printf("%f\n", pi); }
Nothing strange here. We have the output we expected.
The strategy here will be to "fool" the compiler to print this as an integer, but if we try the following:
#include <stdio.h> main() { float pi = (float)3.1416; printf("%f\n", pi); printf("%x\n", (int)pi); }
The cast will truncate the decimals. That same would happen if we just do
printf("%x", pi);
The %x will cast to int before reformatting the output to hex.
So, what other alternative we have? Let's try a solution with pointers:
#include <stdio.h> main() { float pi = (float)3.1416; float* f_ptr = π printf("%f\n", pi); printf("%f\n", *f_ptr); printf("%x\n", *((int *)f_ptr)); }
aaaaaand bingo! That third output is the one we expected and correspond to the first image. But, what happened in the code?
The second output is just for reference and it just shows that derefencing the pointer will get us the value of "pi"
But the third output, let me explain myself:
printf("%x\n", *((int*)f_ptr));
Here what it is done in the second argument is that the pointer to float (float) is casted to int* . That's the beauty of C, it allows the programmer to tell the compiler "Ok, I know I'm giving you a float* but let's pretend this in this case a pointer to int" and so, once we dereference it (leftmost *, giving us an int) and convert the output to hex we get the expected output.