0

I am trying to print out IEEE754 after taking integer type but it does not show the proper answer for me. I want to pass the integer to the function "void ieee(int x)" in the main method, then it will print out the IEEE754 format.

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int binary(int n, int i) 
{
    int k;
    for (i--; i >= 0; i--)
   {
      k = n >> i;
      if (k & 1)
      printf("1");
      else
      printf("0");
    }
}

typedef union
{
  int f;
  struct
  {
        unsigned int mantissa : 23;
        unsigned int exponent : 8;
        unsigned int sign : 1;
   } field;
} myfloat;

void ieee(int x)
{

int i;

myfloat var = (myfloat)x;



printf("%d ",var.field.sign);

binary(var.field.exponent, 8);
printf(" ");

binary(var.field.mantissa, 23);
printf("\n");
}

int main()
{
int x = 3;
ieee(x);

return 0;       
 }
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Sangmin Choi
  • 33
  • 1
  • 5

2 Answers2

1

You are doing a type punning between an int and a struct type holding the internal representation of a float.

This will give you wrong answers.

If you want to know the floating-point representation of an integer number, the correct result can be obtained by doing a previous cast to float.

int x = 3;
myfloat var;
var.f = (float)x; 
binary(var.field.exponent, 8);
binary(var.field.mantissa, 23);

Besides, take in account that one cannot assume that IEEE floating-point representation is being used for float.
For example, see this link:

Macro __STDC_IEC_559__

On the other hand, bit-fields are not necessarily contiguous in all implementations.

See Bitfield disadvantages.

pablo1977
  • 4,281
  • 1
  • 15
  • 41
  • You also have to know how many bits that are used for the mantissa and the total storage space used, – some May 06 '19 at 04:40
  • By assuming IEEE 754 single precision, as apparently the OP does, the number of bits of mantissa and exponent are right. – pablo1977 May 06 '19 at 04:45
  • Since IEEE 754-2008 it is called **binary32**. – some May 06 '19 at 04:49
  • There is no need for a cast. `var.f = x;` suffices. – Eric Postpischil May 06 '19 at 10:44
  • `__STDC_IEC_559__` indicates that an implementation conforms to IEC 60559, effectively IEEE 754. That is not the same as whether an implementation uses IEEE 754 floating-point formats. An implementation may use IEEE 754 formats without conforming fully, and thus will not set `__STDC_IEC_559__`. So it is not reliable as an indicator of format. – Eric Postpischil May 06 '19 at 10:45
  • 1
    Bit-fields are necessarily contiguous when they fit into the storage unit used by the implementation: C 2018 6.7.2.1 11: “If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.” The actual issues are the allocation order (whether high bits or low bits are used first) and the width of the storage unit used. – Eric Postpischil May 06 '19 at 10:49
0

The following uses a union to reinterpret the representation of a float as a 32-bit unsigned integer. This is valid in C. In C++, a union cannot be used for this, and it is necessary to copy the bytes from a float into an integer, as with memcpy.

#include <limits.h> //  For CHAR_BIT (overkill but demonstrates some portability).
#include <stdint.h>
#include <stdio.h>


static void DisplayFloat(float x)
{
    //  Use a union to reinterpret a float as a 32-bit unsigned integer.
    union { float f; uint32_t u; } t = { x };

    //  Ensure float and uint32_t are the same width.
    _Static_assert(sizeof t.f == sizeof t.u,
        "float and uint32_t must be same width.");

    //  Display the bits of the unsigned integer.
    for (int i = sizeof t.u * CHAR_BIT - 1; 0 <= i; --i)
        putchar('0' + (t.u >> i & 1));
    putchar('\n');
}


int main(void)
{
    DisplayFloat(3);
}
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312