如何在字节数组中读取和写入位
我有一个 unsigned char 缓冲区,我想知道如何向该字节缓冲区写入和读取有符号和无符号位。
在Source Engine中有一个名为bf_write的类,其中两个主要方法(由WriteString、WriteChar、WriteLong等使用)使用两个名为WriteUBitLong<的函数/strong> 和 WriteSBitLong。
提前致谢
I have a unsigned char buffer, and I'm wondering how I would write and read signed and unsigned bits to this byte buffer.
In the Source Engine there is a class named bf_write, which two main methods (used by WriteString, WriteChar, WriteLong, etc.) use two functions named WriteUBitLong and WriteSBitLong.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果位数是编译时常量:
如果不是,请使用
,std::vector,它确实是一个打包的位向量:
你似乎想要使用一个需要将位向量打包在字节数组中的库。在不确切知道它以什么顺序放置位的情况下,我只能注意到:
1)以上所有内容可能会使用至少 32 位整数,其中位顺序为最低 - >最高或最高 - >最低有效
2) Little Endian (Intel/AMD) CPU,这意味着 int 数组的字节占用的内存可能与 int 内的位顺序不一致。如果它是“位 0 是 int 0 的 lsb,...位 32 是 int 1 的 lsb,...”那么在小端中与“位 0 是 char 0 的 lsb,...位”相同32 是 char 4 ..." 的 lsb,在这种情况下,您可以将指向 int 数组的指针转换为指向 char 数组的指针
3) 假设您的位集/向量中字节的本机顺序并不完全是这样图书馆需要,那么您必须创建自己的具有他们想要的布局,或者将副本转录到他们的布局中。
a) 如果一个字节内的位顺序不同,则给出具有相反位的字节的 256 条目查找表将是有效的。您可以使用一个小例程生成该表。
b) 从小<->大端反转字节:
要获取/设置字内的特定位,位#0位于字0的最低有效位中:
显然,如果位组织的规则不同,则必须改变上面的。
使用尽可能宽的 int 有效地处理 CPU,因为 block_t 是最好的(不要忘记更改 block_bits),除非字节序无法与您正在使用的库配合使用。
If the number of bits is a compile-time constant:
If it's not, use Boost.dynamic_bitset
Or, if you're desperate, std::vector, which is indeed a packed bit vector:
You seem to want to use a library that requires bit vectors packed in an array of bytes. Without knowing exactly what order it places the bits in, I can only note that:
1) all of the above will probably use at least 32-bit ints with bits ordered least->most or most->least significant
2) on little endian (Intel/AMD) CPUs, this means that the memory occupied by the bytes an array of ints may not be consistent with the ordering of bits within the int. if it's "bit 0 is the lsb of int 0, ... bit 32 is the lsb of int 1, ..." then that's the same in little endian as "bit 0 is the lsb of char 0, ... bit 32 is the lsb of char 4 ...", in which case you can just cast a pointer to the int array to a pointer to char array
3) supposing the native order of bytes in your bit set / vector isn't exactly what the library needs, then you have to either have to create your own that has the layout they want, or transcribe a copy into their layout.
a) if the order of bits within a byte is different, a 256 entry lookup table giving the byte with bits reversed would be efficient. you could generate the table with a small routine.
b) to reverse bytes from little<->big endian:
To get/set a particular bit within a word, with bit #0 in the least significant bit of word 0:
Obviously if the rule for bit organization differs, you have to change the above.
Using the widest possible int your CPU processes efficiently as block_t is best (dont' forget to change
block_bits
), unless the endianness doesn't work out w/ the library you're using.我认为几个宏就足够了:
此外,交换字节顺序可以以更快的方式完成。例如,对于 64 位整数 v,以下操作交换其字节顺序:
I think a few macros are enough:
In addition, swapping endianness can be done in a faster way. For example, for a 64-bit integer v, the following operations swap its endianness: