2

我在我的软件中做了很多位向量操作。例如:假设我需要存储有关候选人“n”的布尔信息,我执行以下操作:

uint64_t *information_vector;
uint32_t pos = n / 64;
uint32_t bit_pos = n % 64;

information_vector[pos] |= (1 << bit_pos);

我在阅读该信息时遵循类似的程序:

uint32_t pos = n / 64;
uint32_t bit_pos = n % 64;
if (information_vector[pos] & (1 << bit_pos)) {
       // do something
}

同时,我还将information_vector写入磁盘并再次读取。现在,我正在尝试解决一个让我做噩梦的错误,让我觉得 Endianess 可能是这里的罪魁祸首,但我无法解释。有什么办法可以查吗?这种位向量操作通常是安全的并且跨架构吗?

我还看到,在代码的某处,我在另一个位向量中为同一候选者设置了一些其他信息:

uint8_t byte_position = n / 8;
uint8_t bit_position = n % 8;
another_information_vector[byte_position] |= (1 << bit_position);

我通常通过对这些位向量进行与运算来找到一组共同的属性。

4

3 回答 3

1

一般来说,如果您总是使用相同的类型(在您的情况下uint64_t)访问您的位向量,并且您访问数据的所有系统的字节序都是相同的,那么字节序不会成为问题。

不过,让自己放心的最简单方法是将对象的地址转换为char*并取消引用,这将让您按照它们在内存中的排列顺序一次看到一个字节。

更新:我刚刚观察到您的第三个代码块似乎是byte_position通过n % 8.

如果你有时写出一个数组uint64_t,有时把它当作一个数组uint8_t,那么如果你的系统是小端序,你的结果可能会出乎意料。

避免这个问题的最好方法是保持你的类型一致。

To make this problem more concrete, consider the following example:

#include <stdio.h>
#include <stdint.h>

int main(){
    uint64_t myVector = 1 << 2; // set second bit of LSB
    uint8_t * ptr = (uint8_t *) &myVector;
    int i;
    for (i = 0; i < 8; i++)
       printf("%x\n", ptr[i]);
}

在我的 little-endianx86系统上,这将打印4后跟 7 0,因为最高有效字节存储在uint64_t. 如果您习惯于考虑从最高位到最低位,从左到右排列的位,这可能与您的直觉背道而驰。

于 2014-04-23T19:46:46.503 回答
1

这在 CPU 内的架构中肯定是字节序安全的。从一种架构写入磁盘,然后在不同的架构上读取它取决于您如何将其读取和写入磁盘。这与将任何多字节数写入磁盘并将其读回时遇到的问题没有什么不同。两端都必须对该数字进行相同的解释。如果在此示例中您只是将 8 个字节写入磁盘,然后在不同的字节序架构上读取它们,那么您将交换字节。

于 2014-04-23T19:54:47.143 回答
1

在大多数情况下,最安全的变体是在字节级别上进行操作,因此除数为 8。OTOH 在某些情况下可能不是最理想的。与字访问相比,有些架构不能直接访问字节,或者访问代价高昂。

在一台小型机器上,选择任何合理的除数(8、16、32、64)时,相同的方法不变。例如,对于位索引 22,字节级访问处理索引为 2 的字节的编号为 6 的位;短字访问用 1 处理短字的第 6 位;等等。

在大端机器上,这需要替换为1 << bit_position, 1 << (BITS_PER_CELL-1-bit_position)or (same) HIGHEST_BIT >> bit_position,其中 HIGHEST_BIT 是 0x80 代表 uint8_t,0x80000000 代表 uin32_t 等。而且,位索引 0 表示字节 0 的 MSB,而不是小端它表示字节 0 的 LSB 的情况。

(在串行线路上可以看到类似的效果。在 RS232 或以太网中,字节从 LSB 传输到 MSB。MAC 地址中的单个/组位是线路上的第一个位,但它是第一个八位字节的 LSB。)

于 2014-04-23T20:18:52.827 回答