C# 将 5 个整数打包为 1
C# Pack 5 integers into 1
我正在尝试使用移位操作将 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;
}
但是,我无法将号码解压回来。
谁能指导我做错什么?
谢谢。
为了打包值 0..999
,您需要 十 位,而不是八位。十个会给你值 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);
}
另一种存储数字的方法。有点不同。但是,我想我会把它呈现给你。基本上,我们只是在模拟 "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 来容纳更多数字。
我正在尝试使用移位操作将 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;
}
但是,我无法将号码解压回来。 谁能指导我做错什么? 谢谢。
为了打包值 0..999
,您需要 十 位,而不是八位。十个会给你值 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);
}
另一种存储数字的方法。有点不同。但是,我想我会把它呈现给你。基本上,我们只是在模拟 "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 来容纳更多数字。