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?
CodePudding user response:
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
CodePudding user response:
When you do this:
uint32_t temp = (uint32_t)input;
You're converting a float
to a uint32_t
. When you convert a floating point type to an integer type, any fractional part is truncated. So temp
contains the value 25. You then (after flipping the bits twice) assign that value to output
which gets printed.
CodePudding user response:
Reinterpret cast instead of convert
assert(sizeof(float) == sizeof(uint32_t));
uint32_t temp = *(uint32_t *)&input;
...
float output = *(float *)&checker;