Home > Software engineering >  Why 1's complement of float variable is not appropriate?
Why 1's complement of float variable is not appropriate?

Time:09-07

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;
  • Related