Search code examples
c#binaryfloating-pointieee-754numerical

How do I save a floating-point number in 2 bytes?


Yes I'm aware of the IEEE-754 half-precision standard, and yes I'm aware of the work done in the field. Put very simply, I'm trying to save a simple floating point number (like 52.1, or 1.25) in just 2 bytes.

I've tried some implementations in Java and in C# but they ruin the input value by decoding a different number. You feed in 32.1 and after encode-decode you get 32.0985.

Is there ANY way I can store floating point numbers in just 16-bits without ruining the input value?

Thanks very much.


Solution

  • You could store three digits in BCD and use the remaining four bits for the decimal point position:

    52.1 = 521 * 10 ^ -1 => 0x1521
    1.25 = 125 * 10 ^ -2 => 0x2125
    

    This would give you a range from 0.0000000000000001 to 999. You can of course add an offset for the decimal point to get for example the range 0.0000000001 to 999000000.


    Simple implementation of four bit used for decimal point placement, and the rest for the value. Without any error check, and not thoroughly checked. (May have precision issues with some values when using != to compare doubles.)

    public static short Encode(double value) {
      int cnt = 0;
      while (value != Math.Floor(value)) {
        value *= 10.0;
        cnt++;
      }
      return (short)((cnt << 12) + (int)value);
    }
    
    public static double Decode(short value) {
      int cnt = value >> 12;
      double result = value & 0xfff;
      while (cnt > 0) {
        result /= 10.0;
        cnt--;
      }
      return result;
    }
    

    Example:

    Console.WriteLine(Encode(52.1));
    Console.WriteLine(Decode(4617));
    

    Output:

    4617
    52.1