C++ Primer Exercise 4.25 转换二进制数

C++ Primer Exercise 4.25 converting binary number

我对 C++ Primer 中的练习 4.25 有疑问:

练习 4.25:~'q' << 6 在 32 位机器上的值是多少 整数和 8 位字符,使用 Latin-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的。 我希望有更多的数字。在线转换器也给出了不同的结果。

在此先感谢您的帮助。

~'q' << 6
= (~'q') << 6
= (~113) << 6
= (~(0 0111 0001)) << 6
= 1 1000 1110 << 6
= -7296

您可能忘记在 113 前面添加一些 0

I don't understand how is it converted to -7296.

它(第二个值)是 有符号 2 的补码的小数

为了回答这个问题,我们需要分析部分表达式是什么类型以及运算符的优先级是什么。

这个可以参考character constant and operator precedence.

'q'表示第一个link:

中描述的int

single-byte integer character constant, e.g. 'a' or '\n' or ''. Such constant has type int ...

'q' 因此相当于其 Latin-1 代码(二进制 01110001)的 int 值,但扩展为适合 32 位整数:00000000 0000000 00000000 01110001.

运算符 ~ 在运算符 << 之前,因此将首先执行按位求反。结果是11111111 11111111 11111111 10001110.

然后执行按位左移(删除值的左侧 6 位并在右侧用 0 填充):11111111 11111111 11100011 10000000.

现在,关于问题的后半部分:cout << (~'q' << 6) << endl; 将此值解释为 int(有符号)。 standard 状态:

However, all C++ compilers use two's complement representation, and as of C++20, it is the only representation allowed by the standard, with the guaranteed range from −2N−1 to +2N−1−1 (e.g. -128 to 127 for a signed 8-bit type).

在 32 位机器上 11111111 11111111 11100011 10000000 的二进制补码结果为十进制 -7296 的二进制代码。 这个数字并不像您预期​​的那样大,因为当您从 -1 十进制(11111111 11111111 11111111 11111111 二进制)开始向下计数时,二进制表示都有很多前导 1-s。最左边的位是 1 表示负数,0 表示正数。当您将负值扩展到更多位(例如,从 32 位到 64 位)时,您将在左侧添加更多 1,直到达到 64 位。可以找到更多信息 here. And here is an online converter.