Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitwise unpacking a long into two numbers

I am struggling to unpack my data from a long type to two numbers. Not sure where i am going wrong.

I create a unique number from two numbers by packing them into a long:

    public static long Squeeze(float x, float y)
    {
        return ((long)x << 32) | (long)y;
    }

So the long consists for 4 bytes for x then 4 bytes for y.

Then i am trying to get the numbers back out with:

float x = (float)(hash >> 32);
float y = (float)(hash | int.MaxValue); // this should be 1111 1111 1111 1111 i think

But it doesn't seem to work, x appears to be correct, but y is giving me numbers that it should not.

Also it needs to work for negative numbers too.

Example:

(2.0, 9.0) => Packed: 8589934601 => Unpacked: (2, 1.073742E+10)
(-1.0, -1.0) => Packed: -1 => Unpacked: (-1.0, -2147484000.0)
like image 832
WDUK Avatar asked Dec 28 '25 22:12

WDUK


1 Answers

You should use BitConverter instead of casting:

public static long Squeeze(float x, float y)
{
    var bytes = new byte[8];
    BitConverter.GetBytes(x).CopyTo(bytes, 0);
    BitConverter.GetBytes(y).CopyTo(bytes, 4);
    return BitConverter.ToInt64(bytes, 0);
}

and

public static void Unpack(long value, out float x, out float y)
{
    var bytes = BitConverter.GetBytes(value);
    x = BitConverter.ToSingle(bytes, 0);
    y = BitConverter.ToSingle(bytes, 4);
}

As long as you're not transferring the byte array out of the program, it doesn't matter whether the system uses little endian or big endian byte ordering. If you need to know, you can check BitConverter.IsLittleEndian.

like image 70
Patrick Roberts Avatar answered Dec 31 '25 11:12

Patrick Roberts



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!