我试图通过位掩码在32位int中存储四个独立的5位值(0-31),但是无法正确设置值并从掩码int中获取单个值用于存储。
任何人都可以帮我吗?
编辑:
对不起外部链接 - 这里有一些JavaScript演示了我想要实现的目标(但是在bitmasks而不是十进制代数中):
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);
}
}
Set函数的byref版本用于更少的分配:
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;
}
}
答案 0 :(得分:4)
如果没有更具体的问题,特别是您展示了迄今为止的代码并解释了您在使其工作方面遇到了麻烦 ,很难确切知道什么最好的答案是。
也就是说,这里有几个示例方法可能会指向正确的方向:
// Stores the given value in storage at the given index
int Set(int storage, int value, int index)
{
int shiftCount = index * 5,
mask = 0x1f << shiftCount;
return (storage & ~mask) | (value << shiftCount);
}
// Retrieves the value stored in storage at the given index
int Get(int storage, int index)
{
int shiftCount = index * 5,
mask = 0x1f << shiftCount;
return (storage & mask) >> shiftCount;
}
上面的Set()
方法获取storage
中的当前值,清除要存储五位值的位范围内的所有位,然后使用{{1运算符用于存储该五位值,首先将该值的位移到正确的位置。
|
方法执行反向操作。它在存储值的位范围内屏蔽(清除)所有位而不是,然后将存储的位向下移动到Get()
的最低有效位5位。在返回结果之前。
注意:
int
方法的value
实际上是否适合五位(即小于Set()
)会更好。< / LI>
修改强>
这是一个简单的控制台程序,演示了上面的示例数据:
0x20