Search code examples
integerfixed-point

How to convert integer or float to S16.16 fixed point format


My question is about how to convert an integer or float to S16.16 format.

I'm reading some code that say converting an integer or float to S16.16 format can be achieved by multiplying by 2^16 to align the zero point.

Is this correct and could somebody explain how it works please?


Solution

  • The ".16" in S16.16 means that the 16 lowest bits are actually after the radix point. For example: (the funny symbol means "corresponds to")

    0x00010000 ≘ 1.0
      ^^^^
      the whole number part
    0x00028000 ≘ 2.5
    0x0003C000 ≘ 3.75
          ^^^^
          the part after the radix point
    

    Or in other words, the way a raw value is interpreted is as: value = raw / 216

    In order to convert a normal value to that format, we need to multiply by 216 (which cancels out with that implicit division).

    Examples:

    1 << 16 = 0x00010000 ≘ 1.0
    int(3.75 * pow(2.0, 16)) = int(245760.0) = 0x0003C000 ≘ 3.75