关于C++ Primer的练习4.25,我有一个问题:
练习4.25:在具有32位in和8位字符的机器上~'q‘<< 6的值是多少?该机器使用拉丁-1字符集,其中'q’的位模式为01110001?
我有二进制的解决方案,但我不明白这是如何转换为int的:
int main()
{
cout << (std::bitset<8 * sizeof(~'q' << 6)>(~'q' << 6))<<endl;
cout << (~'q' << 6) << endl;
return 0;
}执行后,将打印以下两行:
11111111111111111110001110000000
-7296
第一行是我所期望的,但我不明白它是如何转换成-7296的。我预计会有更大的数目。此外,在线转换器给出了一个不同的结果。
提前谢谢你的帮助。
发布于 2021-12-04 11:57:59
为了回答这个问题,我们需要分析哪些类型是部分表达式,以及所使用的操作符的优先级是什么。
'q'表示第一个链接中描述的int:
单字节整数字符常量,例如'a‘或’n‘或'\13’。这样的常数有int型..。
因此,'q'相当于拉丁文-1代码(二进制01110001)的int值,但扩展为适合32位整数:00000000 0000000 00000000 01110001。
运算符~先于运算符<<,因此将首先执行按位否定。结果为11111111 11111111 11111111 10001110。
然后执行位左移位(删除值的左边6位,并在右边填充0-s ):11111111 11111111 11100011 10000000。
现在,关于问题的后半部分:cout << (~'q' << 6) << endl;将此值解释为int (签名)。标准指出:
然而,所有C++编译器都使用两种补码表示形式,而到C++20为止,它是标准允许的唯一表示形式,保证范围从−2N−1到+2N−1−1 (例如,签名8位类型的-128到127 )。
在32位机器上,11111111 11111111 11100011 10000000的两个补值将导致十进制-7296的二进制代码。这个数字并不像您预期的那样大,因为当您从-1小数点开始(11111111 11111111 11111111 11111111二进制)并向下计数时,二进制表示都有大量的前导1-s。最左边的位是1表示负数,0表示正数。当您将负值扩展到更多位时(例如,从32位到64位),您将向左边添加更多的1-s,直到达到64位。更多信息可以找到这里。这是一种在线转换器。
发布于 2021-12-04 11:47:16
~'q' << 6
= (~'q') << 6
= (~113) << 6
= (~(0 0111 0001)) << 6
= 1 1000 1110 << 6
= -7296你可能忘了在113号前面加上一些0。
发布于 2021-12-04 11:47:33
我不明白它是怎么变成-7296的。
它(第二个值)是签名2的补码的十进制。
https://stackoverflow.com/questions/70225218
复制相似问题