我到处读到人们谈论一点一点地压缩对象的地方。诸如“前三位代表某某,接下来的两位代表这个,十二位代表那个”
我理解为什么需要尽量减少内存使用,但我想不出一个好的方法来实现这一点。我知道我会将它打包成一个或多个整数(或长整数,等等),但我无法想象一种简单的方法来使用它。如果有一个类可以让我从任意长度的二进制字段中获取/设置任意位,那将是非常酷的,它会为我处理好事情,而且我不必胡乱处理 &'s 和 |' s和面具等等。
这种事情有标准模式吗?
我到处读到人们谈论一点一点地压缩对象的地方。诸如“前三位代表某某,接下来的两位代表这个,十二位代表那个”
我理解为什么需要尽量减少内存使用,但我想不出一个好的方法来实现这一点。我知道我会将它打包成一个或多个整数(或长整数,等等),但我无法想象一种简单的方法来使用它。如果有一个类可以让我从任意长度的二进制字段中获取/设置任意位,那将是非常酷的,它会为我处理好事情,而且我不必胡乱处理 &'s 和 |' s和面具等等。
这种事情有标准模式吗?
来自MSDN:
位数组类
管理一个紧凑的位值数组,表示为布尔值,其中 true 表示该位打开 (1),false 表示该位关闭 (0)。
例子:
BitArray myBitArray = new BitArray(5);
myBitArray[3] = true; // set bit at offset 3 to 1
不过,BitArray 允许您仅设置单个位。如果您想用更多位对值进行编码,则可能无法使用 &'s 和 |'s 以及掩码和其他东西:-)
您可能想查看 .NET Framework 中的BitVector32结构。它允许您定义“部分”,即 int 中的位范围,然后读取和写入这些部分的值。
主要限制是它仅限于单个 32 位整数;这可能是也可能不是问题,具体取决于您要执行的操作。正如 dtb 所提到的,BitArray 可以处理任何大小的位字段,但您一次只能获取和设置一个位 - 不支持 BitVector32 中的部分。
您要查找的内容称为按位运算。
例如,假设我们要用整数的最低有效 24 位表示一个 RGB 值,其中 R 是 23-16 位,G 是 15-8 位,B 是 7-0 位。
您可以将 R 设置为 0 到 255 之间的任何值,而不会影响其他位,如下所示:
void setR(ref int RGBValue, int newR)
{
int newRValue = newR << 16; // shift it left 16 bits so that the 8 low-bits are now in position 23-16
RGBValue = RGBValue & 0x00FF; // AND it with 0x00FF so that the top 16 bits are set to zero
RGBValue = RGBValue | newRValue; // now OR it with the newR value so that the new value is set.
}
通过使用按位 AND 和 OR(以及偶尔更奇特的操作),您可以轻松设置和清除较大值的任何单个位。
与其使用工具包或特定于平台的包装类,我认为你最好咬紧牙关学习你的 &s 和 |s 和 0x04s 以及所有按位运算符的工作原理。总的来说,大多数项目都是这样完成的,而且操作非常快。大多数语言的操作几乎相同,因此您不会依赖于某些特定的工具包。