【发布时间】:2026-02-03 03:30:01
【问题描述】:
需要将以下内容打包解包成 UInt64
UInt25
UInt5
UInt7
UInt27
具有以下用于从 UInt32 打包和解包 UInt27 和 UInt5
但我无法通过 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 的
union- 或使用long int(您的机器上是 64 位),然后进行移位和添加...跨度> -
你正在循环
i,一个 `uint16',到 2^27。不是你唯一的问题,但不会工作......如果结果溢出,结果是未定义的,所以使用可以保存结果的类型! -
@Floris 同意我应该是 Unint32。那是测试的问题。那打包和解包不起作用怎么办?
-
您需要 64 位,而不是 32 位,才能使事情适应。当您将内容转换为
UInt32时,您会丢弃前 32 位。当前接受的答案并不能保证这一点。如果您的编译器定义了 uint64 类型(或等效类型),那就更好了。如果没有,请自行添加#define uint64 (unsigned long long)。 -
从你所说的我得出的结论是,在你的平台/编译器上,ulong 是 UInt64。这意味着接受的答案(它很干净,实际上非常接近我在原始评论中提出的建议)对您来说非常有效 - 您接受它是正确的。但我希望看到@BenVoigt 改进答案以明确指出
ulong===UInt64,因为标准不保证这一点。