Binary Fraction Representation

30 Jun 2014

When dealing with drivers or low-level code you do have to care about the binary representation of number. Most of the times this means that you need to know how to convert between decimal and binary numbers. This is something we as software developers do often so we know how to do it and the programming languages that we use do it for us.

I had a case once where I needed to fill in a memory mapped register with a fraction, and this fraction had to be represended using 5 bits. Now this is a case that I want to share with other developers since I find the code rather amusing. Here is the code that I ended up with in the end.

static int fraction(float f, int precision)
{
  int result = 0;
  float rest = f - (int)f;
  while (precision) {
    result = result << 1;
    rest = rest * 2;
    if (rest >= 1.0)
    {
      result = result | 1;
      rest = rest - 1.0;
    }

    precision--;
  }

  return result;
}

Let's go through the code. The input f is some floating point number which is the value that you want to represent and the input precision is the number of bits you want to use to represent value.

The first thing I do is to truncate the input value so I only deal with the fraction. So for instance if you send in 1.25 to this function it would start by removing 1 to get 0.25.

The rest of the algorithm follows the standard way of converting a fraction to binary and that is to divide by 1/2 (which is the same as multiply by 2) and if the result is >= 1.0 you output a 1 and subtract 1.0 from the result, if the result is < 1.0 then you output a 0.

Let's do this by hand with the value 0.27 and try to represent it using 4 bits.

0.27 * 2 = 0.54    => 0
0.54 * 2 = 1.08    => 1
0.08 * 2 = 0.16    => 0
0.16 * 2 = 0.32    => 0
Result is 0100 which is the same as
0*1/2 + 1*1/4 + 0*1/8 + 0*1/16 = 0.25

That's a nice numeric algorithm for those special fractional days.