I am writing a simple function to check the 1's compliment of a floating number. This is the code I have written to verify the value:
#include <stdio.h>
#include <stdint.h>
int main()
{
float input = 25.456;
printf("input val = %f\n",input);
uint32_t temp = (uint32_t)input;
uint32_t toggleval = ~temp;
uint32_t checker = ~toggleval;
float output = (float)checker;
printf("output val = %f\n",output);
return 0;
}
After running this code, I can see the output as
input val = 25.455999
output val = 25.000000
Why are those decimal places different? I am expecting the same values as the input float value? Anything wrong here?
Your attempts at "type-punning" don't do what you think. The uint32_t temp = (uint32_t)input
assignment does not return the binary representation of the float
as a unit32_t
; rather, it converts the value of the float
to an unsigned integer (by truncation of the non-integral part). The other cast (back to a float
) does a similar (but reversed) conversion.
For such type-punning (in C but not in C++) you can use a union that has a float
and a uint32_t
occupying the same memory; then, you can write to one and read from the other:
#include <stdio.h>
#include <stdint.h>
int main()
{
union { float f; uint32_t u; } pun;
float input = 25.456f;
printf("input val = %f\n", input);
pun.f = input; // Write the float part ...
uint32_t temp = pun.u; // ... but read as a unit32_t
uint32_t toggleval = ~temp;
uint32_t checker = ~toggleval;
pun.u = checker; // Write the unit32_t ...
float output = pun.f; // ... but read as a float
printf("output val = %f\n", output);
return 0;
}
Related reading: Unions and type-punning