【问题标题】:C# Pack 5 integers into 1C# 将 5 个整数打包成 1
【发布时间】:2018-08-12 03:35:17
【问题描述】:

我正在尝试使用位移操作将 5 个整数(每个最多 999 个)打包和解包成一个唯一的整数:

static UInt64 Combine(uint a, uint b, uint c, uint d, uint e)
    {
        return (a << 48) | (b << 32 ) | (c << 16) | (d << 8) | e;
    }

但是,我无法解开该号码。 谁能指导我做错了什么? 谢谢。

【问题讨论】:

  • 如果你不向我们展示你正在做什么来试图解开它们,我们怎么能告诉你你做错了什么?
  • 您需要 10 位来打包 0-999。 8 位只能让你达到 255。10 位会让你达到 1023。

标签: c# integer bit pack


【解决方案1】:

为了打包值0..999,您需要10 位,而不是8 位。十个会给你0..1023的值,而八个只会给你0..255

所以你需要的功能是这样的:

static UInt64 Combine(
    uint a, uint b, uint c, uint d, uint e
) {
    UInt64 retval = a;
    retval = (retval << 10) | b;
    retval = (retval << 10) | c;
    retval = (retval << 10) | d;
    retval = (retval << 10) | e;
    return retval;
}

然后,要解压它们,只需提取每组十位,一次一个,例如:

static void Extract(UInt64 val, out uint a, out uint b,
    out uint c, out uint d, out uint e
) {
    e = Convert.ToUInt32(val & 0x3ff); val = val >> 10;
    d = Convert.ToUInt32(val & 0x3ff); val = val >> 10;
    c = Convert.ToUInt32(val & 0x3ff); val = val >> 10;
    b = Convert.ToUInt32(val & 0x3ff); val = val >> 10;
    a = Convert.ToUInt32(val & 0x3ff);
}

【讨论】:

    【解决方案2】:

    另一种存储数字的方式。这有点不同。但是,我想我会把它呈现给你。基本上,我们只是在模拟“Unions”:

    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace Unions
    {
        public partial class Form1 : Form
        {
            [StructLayout(LayoutKind.Explicit)]
            struct uShortArray
            {
                [FieldOffset(0)]
                public ushort Bytes01;
                [FieldOffset(2)]
                public ushort Bytes23;
                [FieldOffset(4)]
                public ushort Bytes45;
                [FieldOffset(6)]
                public ushort Bytes67;
    
                [FieldOffset(0)]
                public long long1;
            }
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, System.EventArgs e)
            {
                uShortArray ua = default(uShortArray);
                ua.Bytes01 = 999;
                ua.Bytes23 = 164;
                ua.Bytes45 = 581;
                ua.Bytes67 = 43;
    
                MessageBox.Show($"ua = [Bytes 0 - 1 : {ua.Bytes01}] ... [Byte 2 - 3 : {ua.Bytes23}] ... [Bytes 4 - 5 : {ua.Bytes45}] ... [Bytes 6 - 7 : {ua.Bytes67}] ... [long1 : {ua.long1}]");
    
                uShortArray ua2 = default(uShortArray);
    
                Combine(out ua2, 543, 657, 23, 999);
    
                MessageBox.Show($"ua2 = [Bytes 0 - 1 : {ua2.Bytes01}] ... [Byte 2 - 3 : {ua2.Bytes23}] ... [Bytes 4 - 5 : {ua2.Bytes45}] ... [Bytes 6 - 7 : {ua2.Bytes67}] ... [long1 : {ua2.long1}]");
    
                uShortArray ua3 = default(uShortArray);
                ua3.long1 = ua.long1;  //As you can see, you don't need an extract.  You just assign the "extract" value to long1.
    
                MessageBox.Show($"ua3 = [Bytes 0 - 1 : {ua3.Bytes01}] ... [Byte 2 - 3 : {ua3.Bytes23}] ... [Bytes 4 - 5 : {ua3.Bytes45}] ... [Bytes 6 - 7 : {ua3.Bytes67}] ... [long1 : {ua3.long1}]");
            }
    
            private void Combine(out uShortArray inUA, ushort in1, ushort in2, ushort in3, ushort in4)
            {
                inUA = default(uShortArray);
    
                inUA.Bytes01 = in1;
                inUA.Bytes23 = in2;
                inUA.Bytes45 = in3;
                inUA.Bytes67 = in4;
            }
        }
    }
    

    这个结构只存储 4 个值。但是,您可以使用更大的类型而不是 long 来保存更多的数字。

    【讨论】:

      猜你喜欢
      • 2017-08-17
      • 1970-01-01
      • 2021-12-09
      • 2011-10-11
      • 2014-10-27
      • 1970-01-01
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多