std::bitset
是C++标准库中的一个类,用于表示和操作由固定数量的位组成的二进制序列。
以下是三种获取 std::bitset 对象中从某一位到另一位的值,并以十进制形式输出的方法:
主要区别就是获取掩码的方式。
方法一
std::bitset<8> binary("10101010"); // 假设有一个8位的二进制数
int start = 2;
int end = 5;
// 创建掩码
std::bitset<8> mask = (1 << (end - start + 1)) - 1;
std::cout << mask << std::endl;
// 提取目标位
std::bitset<8> extracted = binary & (mask << start);
std::cout << extracted << std::endl;
// 右偏移
extracted >>= start;
// 输出结果
unsigned long decimalValue = extracted.to_ulong();
std::cout << decimalValue << std::endl;
在上述示例中,创建了一个 std::bitset 对象 binary,表示一个8位的二进制数。
然后,定义了起始位和结束位的索引,即 start 和 end。
创建了一个掩码 mask,并将其移位并减一得到。
然后,使用按位与运算符 & 将 binary 与 (mask << start) 进行按位与运算,以提取目标位。
通过右移 extracted 得到结果,最后将其转换为十进制数并输出。(1 << (end - start + 1)) - 1
解释(1 << (end - start + 1)) - 1
是用于创建掩码的表达式,其含义是:
-
<<
是位移运算符,表示将位向左移动指定的位数。 -
end - start + 1
表示要提取的位数(即结束位减去起始位再加1),例如end
为5,start
为2,那么end - start + 1
的结果就是4,表示要提取4位。 -
(1 << (end - start + 1))
将数字1左移指定的位数,在这里就是将1左移4位,结果为16(二进制表示为 10000)。 -
- 1
将上一步的结果减1,就是将全部位都置为1,得到最终的掩码,例如 16 - 1 的结果就是 15(二进制表示为 1111)。
这样,通过这个表达式得到的掩码中,除了想要提取的位为1,其他位都为0。这样再与要提取的位进行按位与运算,就可以将想要的位提取出来,并清零其他位。美不美?
方法二
std::bitset<8> binary("10101010"); // 假设有一个8位的二进制数
int start = 2;
int end = 5;
// 创建掩码
std::bitset<8> mask = (1<<(end+1)) - (1<<start);//(1 << (end - start + 1)) - 1;
std::cout << mask << std::endl;
// 提取目标位
std::bitset<8> extracted = binary & mask;// (mask << start);
std::cout << extracted << std::endl;
// 右偏移,得到的结果从0位开始
extracted >>= start;
// 输出结果
unsigned long decimalValue = extracted.to_ulong();
std::cout << decimalValue << std::endl;
(1<<(end+1)) - (1<<start)
是一个表达式,用于创建一个掩码,其含义是:
-
<<
是位移运算符,表示将位向左移动指定的位数。 -
end+1
表示结束位的索引加1,这样可以将要提取的位的下一位(即结束位的下一位)设置为1。例如,如果结束位是5,那么end+1
的结果就是6。 -
(1<<(end+1))
将数字1左移指定的位数,在这里就是将1左移6位,结果为64(二进制表示为 1000000)。
同时,也需要创建一个表示起始位的掩码,用于将起始位到最高位的位全部置为0,并将起始位和之前的位全部置为1。这里使用 (1<<start)
来创建起始位掩码,例如,如果起始位是2,那么 (1<<start)
的结果就是4(二进制表示为 100)。
最终,将结束位的掩码与起始位的掩码进行减法操作,得到最终的掩码。
例如,如果结束位是5,起始位是2,那么 (1<<(end+1)) - (1<<start)
的结果就是 60(二进制表示为 111100)。
这样,通过这个表达式得到的掩码中,除了想要提的位为1,其他位都为0。这样再与要提取的位进行按位与运算,就可以将想要的位提取出来,并清零其他位。美不美?
方法三
std::bitset<8> binary("10101010"); // 假设有一个8位的二进制数
int start = 2;
int end = 5;
// 创建掩码
std::bitset<8> mask;
// 注意,bitset的下标是从0开始的
for(int i = start; i < end+1; ++i) {
mask.set(i, true);
}
//std::bitset<8> mask = (1<<(end+1)) - (1<<start);//(1 << (end - start + 1)) - 1;
std::cout << mask << std::endl;
// 提取目标位
std::bitset<8> extracted = binary & mask;// (mask << start);
std::cout << extracted << std::endl;
// 右偏移
extracted >>= start;
// 输出结果
unsigned long decimalValue = extracted.to_ulong();
std::cout << decimalValue << std::endl;
上述示例创建掩码,就很明确,直接复制,之后做&
运行,然后有偏移得到最终结果。美不美?