【发布时间】:2015-04-12 04:31:31
【问题描述】:
我正在尝试通过位掩码将四个独立的 5 位值 (0-31) 存储在 32 位 int 中,但无法正确设置值并从用于掩码的 int 中获取各个值存储。
谁能帮我解决这个问题?
编辑:
对不起,外部链接 - 这是一些 JavaScript 演示我正在尝试实现的目标(但使用位掩码而不是十进制代数):
var s = 0;
var v = [31, 6, 23, 31];
//save values
s = v[0] + (v[1] * 32) + (v[2] * 1024) + (v[3] * 32768);
console.log(s);
//retrieve values
v[3] = parseInt(s / 32768);
v[2] = parseInt((s - (v[3] * 32768)) / 1024);
v[1] = parseInt((s - ((v[3] * 32768) + (v[2] * 1024))) / 32);
v[0] = parseInt(s - ((v[3] * 32768)+ (v[2] * 1024) + (v[1] * 32)));
console.log(v);
//modify values [1] and [2]
s = s - (v[1] * 32) + (9 * 32);
s = s - (v[2] * 1024) + (17 * 1024);
console.log(s);
//retrieve values
v[3] = parseInt(s / 32768);
v[2] = parseInt((s - (v[3] * 32768)) / 1024);
v[1] = parseInt((s - ((v[3] * 32768) + (v[2] * 1024))) / 32);
v[0] = parseInt(s - ((v[3] * 32768)+ (v[2] * 1024) + (v[1] * 32)));
console.log(v);
输出:
1039583
[31, 6, 23, 31]
1033535
[31, 9, 17, 31]
编辑:
感谢 Peter Duniho,我能够使用内置的掩码来制作这些,以便在 32 位整数中保存 6 个 5 位值的一些操作:
uint Get_5_In_32(uint storage, int index)
{
switch (index)
{
case 0:
return (storage & 0x0000001F);
case 1:
return (storage & 0x000003E0) >> 5;
case 2:
return (storage & 0x00007C00) >> 10;
case 3:
return (storage & 0x000F8000) >> 15;
case 4:
return (storage & 0x01F00000) >> 20;
case 5:
return (storage & 0x3E000000) >> 25;
default:
return (0);
}
}
uint Set_5_In_32(uint storage, uint value, int index)
{
if (value > 31) { value = 31; }
switch (index)
{
case 0:
return (storage & 0xFFFFFFE0) | value;
case 1:
return (storage & 0xFFFFFC1F) | (value << 5);
case 2:
return (storage & 0xFFFF83FF) | (value << 10);
case 3:
return (storage & 0xFFF07FFF) | (value << 15);
case 4:
return (storage & 0xFE0FFFFF) | (value << 20);
case 5:
return (storage & 0xC1FFFFFF) | (value << 25);
default:
return (0);
}
}
还有一个 byref 版本的 Set 函数,分配更少:
void Set_5_In_32(ref uint storage, uint value, int index)
{
if (value > 31) { value = 31; }
switch (index)
{
case 0:
storage &= 0xFFFFFFE0;
storage |= value;
break;
case 1:
storage &= 0xFFFFFC1F;
storage |= (value << 5);
break;
case 2:
storage &= 0xFFFF83FF;
storage |= (value << 10);
break;
case 3:
storage &= 0xFFF07FFF;
storage |= (value << 15);
break;
case 4:
storage &= 0xFE0FFFFF;
storage |= (value << 20);
break;
case 5:
storage &= 0xC1FFFFFF;
storage |= (value << 25);
break;
}
}
【问题讨论】:
-
不,基本上我想要实现的是与jsfiddle.net/mj28pk8f/1 等效的c#,但没有算术开销(这需要运行得非常快,因为位掩码是最快的可以得到这就是我需要使用的)。外部 BitArray 类的开销太大。
-
我不太了解 JavaScript,无法知道您拥有的代码是否是使用该语言的最佳方式。但是,我在答案中发布的代码将完成同样的事情,恕我直言,这是一种更简单、更易读、更通用的方式。
-
当您交换班次和掩码的顺序时,您的代码将更具可读性,因为在这种情况下,掩码将始终为
0x1F。 -
谢谢 - 它适用于 Get 函数,但我需要一个特定的掩码才能使其适用于 Set 函数吗?