0
votes

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?

1
After the assumed 1, the first bit represents 1/2, the next 1/4, then 1/8, etc. So 111000... is 1 + .5 + .25 + .125 = 1.875. Your series of negative powers is one way to do that, but probably slower and less accurate than just using a lookup table. All the values in the lookup table will be exact.Lee Daniel Crocker
If he starts with x=0.5 and then divides x by 2.0 on each iteration of a loop, then all of the values will be exact, because all of those numbers have an exact representation. And at the end of the day, he will get exactly what he started with, but with the exponent set equal to the bias. So that's a rather pointless exercise when you can just set the exponent equal to the bias.user3386109
A note to your tutor: using types with implementation defined width is bad practice. Use fixed width types instead.too honest for this site
Tip: compare results with printf("%a\n", x); which does a lot of this for you.chux - Reinstate Monica
"However, I have not been able to do this conversion" --> post the code you tried.chux - Reinstate Monica

1 Answers

-1
votes
  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.