Search code examples
c#javascript.netfloating-pointbitmask

How can I encode two numbers in a single Integer?


I have the need to store a range of values (like 25-50 or 100-200), however to avoid a lot of database re-design and other work, I want to use a single Int32 to store both these numbers. I realize that I would only then have 16 bits for each number, but that's fine.

So, with two integer values this is pretty easy. I can do something like:

int mask = 50; //Right bits will have 50
mask |= (25 << 16); //Left bits will have 25

Console.WriteLine("Mask is: {0}", mask);
Console.WriteLine("Left is: {0}", (mask >> 16));
Console.WriteLine("Right is: {0}", (mask & 0xFFFF));

Now, I have the right 16 bits storing the value 50, and the left 16 bits storing the value 25.

So what's the question?

Now, I want to use the same technique but I want to store two non-integers. For example, 1.5 and 1.75, or 2.00 and 2.25. .NET doesn't seem to support bit shift operators on float, single, double or decimal. Plus, I need to also read these values eventually in Javascript so it's doubtful whatever bit encoding floating points use would be completely compatible between platforms.

What's the best way to do this? One approach I'm considering is just using integers, but dividing everything by 1000. That would give me 3 decimal point precision in both numbers, though I'd have to store the whole thing as a long to store anything over 65. I'm not sure if this is the best approach though. Maybe there's something easy I'm missing.


Solution

  • A little math could solve that.

    First fix your precision, say 2 digits and your numbers range till 1000

    both = Math.Round(num1, 2) * 10000 + Math.Round(num2, 2);
    

    First 4 digits are for num1 and then you have num2.

    You can get them back reversing the process.