Skip to content

Instantly share code, notes, and snippets.

@JimBobSquarePants
Created July 6, 2016 07:20
Show Gist options
  • Save JimBobSquarePants/4e750b44834cfc1ad97fb1536733a8dd to your computer and use it in GitHub Desktop.
Save JimBobSquarePants/4e750b44834cfc1ad97fb1536733a8dd to your computer and use it in GitHub Desktop.
Packing to and from different numerical types.
// How do I get these two sets of methods to return the same output value?
void Main()
{
uint x1 = PackUint(0.5f, 1, 0.5f, 1);
byte[] b1 = ToBytes(x1);
x1.Dump(); // 4286644096
b1.Dump(); // 128, 255, 128, 255 RIGHT! :)
ulong x2 = PackUlong(0.5f, 1, 0.5f, 1);
byte[] b2 = ToBytes(x2);
x2.Dump(); // 18446603340516130816
b2.Dump(); // 255, 128, 0, 255 WRONG! :(
}
// Define other methods and classes here
public static ulong PackUlong(float r, float g, float b, float a)
{
return ((ulong)Math.Round(r * 65535f) << 32) |
((ulong)Math.Round(g * 65535f) << 16) |
(ulong)Math.Round(b * 65535f) |
((ulong)Math.Round(a * 65535f) << 48);
}
private static uint PackUint(float r, float g, float b, float a)
{
return ((uint)Math.Round(r * 255f) << 16) |
((uint)Math.Round(g * 255f) << 8) |
(uint)Math.Round(b * 255f) |
((uint)Math.Round(a * 255f) << 24);
}
public static byte[] ToBytes(ulong packed)
{
return new[]
{
(byte)((packed >> 16) & 255),
(byte)((packed >> 8) & 255),
(byte)(packed & 255),
(byte)((packed >> 24) & 255)
};
}
public static byte[] ToBytes(uint packed)
{
return new[]
{
(byte)((packed >> 16) & 255),
(byte)((packed >> 8) & 255),
(byte)(packed & 255),
(byte)((packed >> 24) & 255)
};
}
@JimBobSquarePants
Copy link
Author

How do I get these two sets of methods to return the same output value?

The uint based methods work perfectly but the ulong ones fail.

@cfallesen
Copy link

I don't think you got your ToBytes(ulong packed) shift values updates. Should probably shift by 16, 32 and 48 bits. I haven't tested the modified code though.

@JimBobSquarePants
Copy link
Author

Yeah I tried that originally actually. This gives me 0, 255, 0, 255 which is wrong.

@cfallesen
Copy link

Think I got it now:

    public static byte[] ToBytes(ulong packed)
    {
        return new[]
        {
            (byte)((packed >> 40) & 255),
            (byte)((packed >> 24) & 255),
            (byte)((packed >> 8) & 255),
            (byte)((packed >> 56) & 255)
        };
    }

Have to remember to use the most significant 8 bits.

I even tried out the code this time :-)

@JimBobSquarePants
Copy link
Author

Perfect thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment