将多个整数打包和解包成一个Uint64

本文关键字:和解 包成一 Uint64 包和解 整数 | 更新日期: 2023-09-27 18:10:08

需要将以下内容打包和解包为UInt64
UInt25
UInt5
UInt7
UInt27

打包和拆包UInt27和UInt5到UInt32
但是我不能超过2
我的专业是数学(不是计算机科学)

UInt32 highlow;
UInt32 high;
byte  low;
int two27 = (Int32)Math.Pow(2, 27);
for (UInt32 i = 0; i < two27; i++)
{
    highlow = ((UInt32)i) << 5;
    high = highlow >> 5;
    if (high != i)
    {
        Debug.WriteLine("high wrong A " + high.ToString() + " " + i.ToString());
    }
    for (byte j = 0; j < 32; j++)
    {
        highlow = (((UInt32)i) << 5) | j;
        high = highlow >> 5;
        if (high != i)
        {
            Debug.WriteLine("high wrong B " + high.ToString() + " " + i.ToString());
        }
        low = (byte)(highlow & 0x1f);
        if (low != j)
        {
            Debug.WriteLine("low wrong " + low.ToString() + " " + j.ToString());
        }
    }               
}

基于接受答案的代码(未测试完整循环,i27循环到达2)

UInt32 bits27;
UInt32 bits25;
UInt32 bits7;
UInt32 bits5;
UInt32 int27 = (UInt32)Math.Pow(2,27);
UInt32 int25 = (UInt32)Math.Pow(2,25);
UInt32 int7  = (UInt32)Math.Pow(2,7);
UInt32 int5  = (UInt32)Math.Pow(2,5);
UInt64 packed;
//ulong packed = (bits27) | ((ulong)bits25 << 27) | ((ulong)bits7 << 52) | ((ulong)bits5 << 59);
for             (UInt32 i27 = 0; i27 < int27; i27++)
{
    for         (UInt32 i25 = 0; i25 < int25; i25++)
    {
        for     (UInt32  i7 = 0;  i7 <  int7; i7++)
        {
            for (UInt32  i5 = 0;  i5 <  int5; i5++)
            {
                packed = (UInt64)(i27) | ((UInt64)i25 << 27) | ((UInt64)i7 << 52) | ((UInt64)i5 << 59);
                bits27 = (UInt32)(packed & ((1 << 27) - 1));
                bits25 = (UInt32)((packed >> 27) & ((1 << 25) - 1));
                bits7 =  (UInt32)((packed >> 52) & ((1 << 7) - 1));
                bits5 =  (UInt32)((packed >> 59) & ((1 << 5) - 1));
                if (bits27 != i27) Debug.WriteLine("bits27 != i27");
                if (bits25 != i25) Debug.WriteLine("bits25 != i25");
                if (bits7  != i7)  Debug.WriteLine("bits7  !=  i7");
                if (bits5  != i5)  Debug.WriteLine("bits5  !=  i5");
            }
        }
    }
}

将多个整数打包和解包成一个Uint64

移位运算符是正确的解决方案,但请注意,它们不会自动使结果比输入宽——您需要强制转换输入。

:

ulong packed = (bits27) | ((ulong)bits25 << 27) | ((ulong)bits7 << 52) | ((ulong)bits5 << 59);

解压:

bits27 = (uint) (packed        & ((1 << 27) - 1));
bits25 = (uint)((packed >> 27) & ((1 << 25) - 1));
bits7  = (uint)((packed >> 52) & ((1 <<  7) - 1));
bits5  = (uint)((packed >> 59) & ((1 <<  5) - 1));

将数字转换为二进制,填充或截断为正确的长度,将它们连接起来,然后从二进制构造64位类型似乎要容易得多。

var packedInt64 = Convert.ToInt64(Convert.ToString(ui25, 2).PadLeft(25, '0') +
                                  Convert.ToString(ui5, 2).PadLeft(5, '0') +
                                  Convert.ToString(ui7, 2).PadLeft(7, '0') +
                                  Convert.ToString(ui27, 2).PadLeft(2, '0'), 2);
打开

:

var binary = Convert.ToString(packedInt64, 2);
ui25 = Convert.ToUInt32(binary.Substring(0, 24));
ui5 = Convert.ToUInt32(binary.Substring(24, 5));
etc.