char c = 255 的值转换为 int

Value of char c = 255 converted to int

我的问题是关于 Stroustrup 的《C++ 编程语言》第 4 版一书中的一段话。他举了一个例子

char c = 255; // 255 is ‘‘all ones,’ ’ hexadecimal 0xFF
int i = c;

以及如何在 char 有符号或无符号的机器上进行转换的说明。

i 的值是多少?不幸的是,答案是不确定的。在 8 位字节的实现中,答案取决于扩展为 int 时“全部”char 位模式的含义。在 char 无符号的机器上,答案是 255。在 char 有符号的机器上,答案是 −1。

我的问题是为什么它会是-1,这不是取决于机器上使用什么二进制数表示吗?如果它使用一个补码,它不是 0(-0) 吗?如果使用二进制补码,它不是 -1 吗?

(在 char 是有符号 8 位类型的情况下)255 不是可表示的值。将不可表示的值转换为带符号的类型会产生实现定义的值(C++20 前)。因此,Stroustrup 在此步骤中进行了一些简化;就标准而言,在这种情况下,结果可能是任何结果。

但假设符号表示是二进制补码,则该值很可能与 255 模 28 一致(在未来的 C++20 标准中,这将变为保证)。与 255 模 28 一致且可表示的值是 -1.

Wouldn't it be 0(-0) if it uses ones' complement

可能(直到 C++20)。但是 ones 的补语已经过时了,几乎不再使用了。因此,正如我所说,似乎 Stroustrup 似乎选择了简化解释并假设了二进制补码。或者,也许他在写的时候就想到了未来的标准;或者可能提出了标准更改以使他的书正确:)

我们来看文章Signed number representations

啊哈!

我们可以看到提到了5种表示形式:

  • 未签名
  • 符号和大小
  • 个数的补数
  • 补码
  • 偏移二进制
  • 基础 −2

(出于好奇 - 也可以使用更多 Negative base

让我们看看 Comparison table 的 4 位数。

扩展到 1 的 8 位我们看到:

  • 无符号 = 255
  • 符号和大小 = -127
  • 个数的补码 = -0
  • 补码 = -1
  • 多余 127 = 127
  • Base −2 = hm ...我需要考虑一下

所以 Stroustrup 是正确的:

Unfortunately, the answer is undefined. On an implementation with 8-bit bytes, the answer depends on the meaning of the ‘‘all ones’’ char bit pattern when extended into an int

但他在以下方面并不完全正确:

On a machine where a char is unsigned, the answer is 255. On a machine where a char is signed, the answer is −1.

引用 C++03 4.7/3:

If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.

假设字节是 8 位,这意味着理论上你会得到以下之一:

  • -127 如果有符号的震级计算机。
  • -0如果自己补电脑。
  • -1如果二进制补码计算机。

前两者在现实世界中几乎不存在。