Search code examples
cfloating-pointieee-754

Format a float using IEEE-754


I have an assignment in C where I'm given a float number and have to print it using the IEEE-754 format:

__(sign)mantissa * 2^(exponent)__

The sign would be either '-' or ' ', the exponent an int value and the mantissa a float value. I also cannot usestructs or any function present in any library other than the the ones in stdio.h (for the printf function). This should be done using bitwise operations.

I was given two functions:

  • unsignedToFloat: given an unsigned int, returns a float with the same bits;
  • floatToUnsigned: given a float, returns an unsigned int with the same bits;

After getting the float representation as an unsigned int, I have managed to determine the sign and exponent of any float number. I have also managed to determine the mantissa in bits. For example, given the float 3.75:

> bit representation: 01000000011100000000000000000000;
> sign: 0 (' ');
> exponent = 10000000 (128 - bias = 1)
> mantissa = 11100000000000000000000

Now, in this example, I should represent the mantissa as "1.875". However, I have not been able to do this conversion. So far, I have tried to create another float as 000000000[mantissa], but it gives me the wrong result (which I now understand why). I was instructed that the mantissa has a 1 in the beginning, meaning in this example, the mantissa would become 1.111, but I wasn't instructed on how exactly to do this. I tried searching online, but couldn't find any way of adding a 1 to the beginning of the mantissa.

I also had the idea of doing this portion by going through every bit of the mantissa and getting its decimal representation, and then adding 1. In this example, I would do the following:

> 11100000000000000000000
> as_float = 2^-1 + 2^-2 + 2^-3
> as_float += 1

However, this approach seems very hack-y, slow and could perhaps give me wrong result.

With this said, I am completely out of ideas. How would I represent the mantissa of a float number as its own thing?


Solution

    1. Convert the float to unsigned int.
    2. Clear the sign bit (using bitwise AND &).
    3. Set the exponent so that it's equal to the bias (using bitwise AND & and OR |).
    4. Convert the modified value from unsigned int to float.
    5. Use printf to print the new value.

    This works because clearing the sign bit and setting the exponent to the bias leaves you with (positive)mantissa * 2^0 = mantissa, so printf will print the mantissa for you.