Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 要计数到字符位的位数_C - Fatal编程技术网

C 要计数到字符位的位数

C 要计数到字符位的位数,c,C,我在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

我在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))
用前者代替字符位,用后者代替3。我仍然很好奇,是否有一种方法可以在不建立表的情况下,将我需要计数的位数计算到一个字节

问题是两个
FIXME
s,其中我移位3位以获得表示n位的字符数,并将索引放入可以找到位的字符数组中


不要再耍聪明了,只要除以字符就行了。编译器将在适当的情况下将其作为移位来实现。

表示n位的字节数。
定义BV#u大小(n)(n/CHAR#u位+n%CHAR#u位?1:0)有什么问题?仅涉及一个除法和一个模。这些是我想用位运算来代替的运算。今天的大型C编译器通常可以用二的幂来优化除法和乘法,所以这可能不像你想象的那么大问题。创建一个“朴素”的解决方案,在启用优化的情况下构建,并检查生成的代码。在决定要使用的方法之前,您还应该进行一些基准测试和测量。如果字符位不是8怎么办?当编译器将替换为常量表达式--'时,为什么需要位运算,或者您可以只存储结果,而不需要执行一个运算time@ThomasMailund:你是说
n
是一个运行时参数吗?好吧,我使用移位掩码版本与除法模数版本相比得到了一个系数2-3的加速。。。但是,无论如何,我可以使用
uint_8
在那里我知道我需要的常量。@ThomasMailund是在使用优化编译时使用的吗?使用-O3发出叮当声。我自己也有点惊讶。对不起,我的错,我得到了50%的加速比,二的幂次,2-3的加速比是当它们不是二的幂次时(我不能使用位运算——我检查了二者,因为我也使用哈希表的索引,其大小可以是素数或二的幂次)。对不起,在实验中发现了一个错误。我的测试函数中的输入是在运行时提供的。当我重写实验使用#定义常数时,我看不出除法和移位之间有什么区别。我的错。
#define BV_BITS_PER_BYTE 8
#define BV_BITS_TO_INDEX_A_BYTE 3