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

问题描述 投票:16回答:2

我正在研究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
c++ sizeof unsigned bitset
2个回答
20
投票

std::bitset的构造函数接受unsigned long long,当你尝试将一个-1(这是~0int中)分配给unsigned long long时,你得到8个字节(64位)的1s。

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


4
投票

当你写int max=~0;时,max将是32位填充1s,解释为整数是-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填充(因为你有一个负值,符号扩展保持这样,通过填充32个最左边的位1s )。

因此,std::bitset的构造函数得到一个填充1s的unsigned long long,它用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(因为你有一个正值,符号扩展保持这样,通过用0填充最左边的32位)。

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

000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111
© www.soinside.com 2019 - 2024. All rights reserved.