为什么std :: bitset建议比sizeof更多的可用位表示有?

时间:2018-04-23 03:59:50

标签: c++ sizeof unsigned bitset

我在C ++中处理一些简单的位操作问题,并在尝试可视化我的步骤时遇到了这个问题。我知道分配给不同基元类型的位数可能因系统而异。对于我的计算机,sizeof(int)输出4,因此我的值有4 char位。我现在也知道一个字节的定义通常是8位,但不一定是这种情况。当我输出CHAR_BIT时,我得到8。因此,我希望int值总共有32位。

然后我可以继续将int的二进制值打印到屏幕上:

int max=~0; //All my bits are turned on now
std::cout<<std::bitset<sizeof(int)*CHAR_BIT>(max)<<std::endl;

$:11111111111111111111111111111111

如果我想要,我可以增加bitset大小:

int max=~0;
std::cout<<std::bitset<sizeof(int)*CHAR_BIT*3>(max)<<std::endl;

$:000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111

为什么会有这么多?我本来期望只有32个,用零填充。取而代之的是,发生了什么?

当我使用与unsigned int大小相同的int重复实验时,额外的内容不会出现:

unsigned int unmax=~0;
std::cout<<std::bitset<sizeof(unsigned int)*CHAR_BIT*3>(unmax)<<std::endl;

$:000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111

2 个答案:

答案 0 :(得分:20)

std::bitset的构造函数需要unsigned long long,并且当您尝试将-1(~0中的int)分配给{unsigned long long时1}},你得到8个字节(64位)的1s。

unsigned int不会发生这种情况,因为您指定的值为4294967295而不是-1,即unsigned long long

中的32 1

答案 1 :(得分:4)

当你写int max=~0;时,max将是32位,填充为1,解释为整数为-1

写作时

std::bitset<sizeof(int)*CHAR_BIT>(max)
// basically, same as
std::bitset<32>(-1)

您需要记住std::bitset构造函数需要unsigned long long。所以你传递给它的-1被转换为64位表示-1,这是64位全部用1填充(因为你有一个负值,符号扩展保持这样,通过用1s填充最左边的32位。

因此,std::bitset的构造函数将unsigned long long全部填充为1,并使用1s初始化您询问的32位。所以,当你打印它时,你得到:

11111111111111111111111111111111

然后,当你写:

std::bitset<sizeof(int)*CHAR_BIT*3>(max)
// basically, same as
std::bitset<96>(-1)

std::bitset构造函数将使用您传递的unsigned long long的值初始化96个最右边的96位,因此这些64位用1填充。其余位(最左边的32位)用零初始化。因此,当您打印它时,您会得到:

000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111

另一方面,当您撰写unsigned int unmax=~0;时,您将所有1分配给unsigned int,因此您获得了UINT_MAX

然后,当你写:

std::bitset<sizeof(unsigned int)*CHAR_BIT*3>(unmax)
// basically, same as
std::bitset<96>(UINT_MAX)

你传递的UINT_MAX被转换为64位表示,这是32位最右边的位填充1s而其余的全部为0(因为你有一个正值,符号扩展保持这样,通过用0s填充最左边的32位。

因此unsinged long long构造函数获取的std::bitset表示为32 0,然后是32 1。它会初始化96个最右边的位,你用32 0s跟随32个1s。其余32个最左边的位(96位)用零初始化。因此,当你打印它时,你得到(64 0s后跟32 1s):

000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111