我在C中实现了位向量的实现,在这里我想避免除法和模运算,而将其替换为(更快的)位运算。所以我把位放在字节(char)中,需要索引到这些数组中,然后再抽出一点。我的实现如下所示:
#include <limits.h> // For CHAR_BIT
#include <stdbool.h> // For defintion of bool
// Number of bytes to represent n bits.
// FIXME: 3 should be log_2(CHAR_BIT).
#define BV_SIZE(n) (((n) >> 3) + 1)
// Remove last byte (divice by CHAR_BIT, i.e. shift by log_2(CHAR_BIT) bits)
// FIXME: 3 should be log_2(CHAR_BIT).
#define BV_CHAR_INDEX(i) ((i) >> 3)
// Mask out last byte (CHAR_BIT bits)
#define BV_LAST_CHAR_MASK (CHAR_BIT - 1)
// Extract which bit index we have
#define BV_BIT_INDEX(i) ((i) & BV_LAST_CHAR_MASK)
// Get the mask for that bit
#define BV_BIT_MASK(i) (1 << BV_BIT_INDEX(i))
// Getter and setter for bits in vector bv
#define BV_GET_BIT(bv, i) ((bool)((bv)[BV_CHAR_INDEX(i)] & BV_BIT_MASK(i)))
#define BV_SET_BIT(bv, i) ((bv)[BV_CHAR_INDEX(i)] |= BV_BIT_MASK(i))
#define BV_UNSET_BIT(bv, i) ((bv)[BV_CHAR_INDEX(i)] &= ~BV_BIT_MASK(i))
问题是两个FIXME,其中我移位了3位以获取表示n位的字符数,并在其中获得了可以找到一位的char数组的索引。在BV_SIZE
中,我不太介意划分,因为我不经常分配位向量,但是在索引到向量时我想避免这种情况。
是否有一种通用的方法来获取需要计数的位数CHAR_BIT
?我已经硬连线到CHAR_BIT
上有8位,并且在我使用的所有体系结构上都是如此,但是如果不是,我可以在编译时获得这个数字吗?
编辑:我当然可以使用uint8_t
作为字节,然后进行定义
#define BV_BITS_PER_BYTE 8
#define BV_BITS_TO_INDEX_A_BYTE 3
并使用前者代替CHAR_BIT
,而后者代替3。我仍然很好奇是否有一种方法可以在不建立表的情况下获取需要计数的位数...?
答案 0 :(得分:1)
问题是两个
FIXME
,其中我移位3位以获取表示n位的字符数,并在其中找到可以找到一位的char数组中的索引。
不要试图变得聪明,只能除以CHAR_BIT
。适当时,编译器将实现此转变。