我在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
答案 0 :(得分:20)
std::bitset
的构造函数需要unsigned long long
,并且当您尝试将-1(~0
中的int
)分配给{unsigned long long
时1}},你得到8个字节(64位)的1s。
unsigned int
不会发生这种情况,因为您指定的值为4294967295而不是-1,即unsigned long long
答案 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