C++基础——简单而强大的bitset

  • basis
  • bitset 的构造
  • bitset的操作
  • 一些高级用法
    • 将Bitsets视为一组标志

一些简单的原子操作,往往能组合出复杂而强大的功能。位操作的深远意义不在于表示一种数值,而是可能的情况数。我虽然暂时不知道bitset能组合出如何复杂的功能,但冥冥之中却有这样的直觉感受。

basis

  • bitset所在的头文件<bitset>

  • 命名空间std

  • bitset<N>属于非类型模板参数

#include <bitset>
std::bitset<8> bs;      

// 模板参数是一个size_t类型的数值(value),而非一个类型
// numeric_limits<size_t>::min() == 0
// std::bitset<8> 表示的二进制位为8位,
// 默认的构造函数将其初始为全0

cout << bs.to_ulong() << endl;      // 0
cout << bs.to_string() << endl;     // 00000000

bitset 的构造

唯一需要注意的是,bitset<>模板类虽然重载了中括号运算符,bs[0]表示的是将该数值转换为二进制时的最末尾元素,而非首位(其意义和数组并不相同)。

std::bitset<8> bs;
//bs[0] = 1; // 0000 0001
//bs[7] = 1; // 1000 0000
  • 默认无参构造
    初始化全部位为0

-十进制或者16进制数值

std::bitset<8> bs(7);
bs.to_string()  // 0000 0111
std::bitset<8> bs(0x07);
bs.to_string()  // 0000 0111

这里也存在一些高大上的构造方式:

bitset<numeric_limits<unsigned short>::digits> bs1(267);
    // 16位 
bitset<numeric_limits<unsigned long>::digits> bs2(267);
    // 32位
  • 用string对象
std::bitset<8> bs("00000111");
bs.to_ulong();      // 7

bitset的操作

成员函数 函数功能
bs.any() 是否存在值为1的二进制位
bs.none() 是否不存在值为1的二进制位
或者说是否全部位为0
bs.size() 位长,也即是非模板参数值
bs.count() 值为1的个数
bs.test(pos) 测试pos处的二进制位是否为1
与0做或运算
bs.set() 全部位置1
bs.set(pos) pos位处的二进制位置1
与1做或运算
bs.reset() 全部位置0
bs.reset(pos) pos位处的二进制位置0
与0做或运算
bs.flip() 全部位逐位取反
bs.flip(pos) pos处的二进制位取反
bs.to_ulong() 将二进制转换为unsigned long输出
bs.to_string() 将二进制转换为字符串输出
~bs 按位取反
效果等效为bs.flip()
os << b 将二进制位输出到os流
小值在右,大值在左

一些高级用法

首先看一个简单实例:

"1000 0000" - > 1
"1000 1000" - > 17

如何实现2进制向10进制的转换,而且二进制的表示形式是一种逆序的形式,即低位在前。

int bin2dec(const string& bin)
{
    std::bitset<8> bs(string(bin.rbegin(), bin.rend()));
    return bs.to_ulong();
}

这里回顾开头引用中的话,bitset的强大之处不在于表示一个二进制的数值,而是表达一种情况数,一个二进制位可以表示两种情况,两个二进制位可以表示4种状况数,3个二进制位可以表达8种状况数,等等。

将Bitsets视为一组标志

enum Color{red, yellow, green, blue, white, black, numColors};
// 初始状态下,全部颜色都未使用
bitset<numColors> usedColors;

// something happens
usedColors.set(red);
usedColors.set(blue);

cout << "bitfield of used colors: " << usedColors << endl;
cout << "bitfield of unused colors: " << ~usedColors << endl;

// process if any color is used 
if (usedColors.any())
{
    for (int c = 0; c < numColors; ++c)
    {   // 貌似只有遍历,而没有提供返回值为1的下标
        if (usedColor[Color(c)])
        {
            // 
        }
    }
}

你可能感兴趣的:(C++,bitset,二进制)