我的问题是关于Stroustrup的C ++编程语言第4版中的一个段落。他带来了一个例子
char c = 255; // 255 is ‘‘all ones,’ ’ hexadecimal 0xFF
int i = c;
并解释如何在char签名或未签名的机器上进行转换。
我的价值是什么?不幸的是,答案是不确定的。在具有8位字节的实现上,答案取决于扩展为int时“全部”字符位模式的含义。在char未签名的机器上,答案是255.在签名char的机器上,答案是-1。
我的问题是为什么它会为-1,它不取决于机器上使用二进制数的表示形式?它是不是0(-0)如果它使用1的补码而-1如果是2的补码?
引用C ++ 03 4.7 / 3:
如果目标类型已签名,则如果可以在目标类型(和位字段宽度)中表示该值,则该值不会更改;否则,该值是实现定义的。
假设字节是8位,这意味着理论上你得到以下之一:
-127
如果签名的计算机。-0
如果一个人的补充计算机。-1
如果两个补充计算机。前两者几乎不存在于现实世界中。
(在char
签名为8位类型的情况下)255不是可表示的值。将不可表示的值转换为有符号的类型会导致实现定义的值(直到C ++ 20)。所以,Stroustrup在这一步骤中简化了一点;就标准而言,结果可能是这种情况下的任何结果。
但假设符号表示是二进制补码,则该值很可能与255模28一致(在未来的C ++ 20标准中,这将成为一种保证)。与255模数28一致且可表示的值为-1。
如果它使用的是补码,它不会是0(-0)
可能(直到C ++ 20)。但是那些补充是古老的,几乎不再使用了。因此,正如我所说,似乎Stroustrup似乎选择简化解释并假设两个补码。或者也许他在写作时心中有未来的标准;或者也许标准的改变是为了让他的书正确:)
我们来看看文章Signed number representations。
啊哈!
我们可以看到提到了5种类型的表示:
(并且好奇 - 可以使用更多的Negative bases)
让我们看看Comparison table的4位数字。
扩展到8位的1
,我们看到:
255
-127
-0
-1
127
所以Stroustrup是对的:
不幸的是,答案是不确定的。在具有8位字节的实现上,答案取决于扩展为int时''all''char位模式的含义
但他并不完全正确:
在char未签名的机器上,答案是255.在签名char的机器上,答案是-1。