考虑下面的程序转换无符号字符到符号的int
void main(){
char t = 179;
printf("%d ",t);
}
输出为-77。 但179二进制表示是
10110011
所以,不应该输出为-51,考虑到第1位被烧焦位。的-77 二进制表示是
11001101
这似乎有点次序颠倒。这是怎么回事?请有人建议。
考虑下面的程序转换无符号字符到符号的int
void main(){
char t = 179;
printf("%d ",t);
}
输出为-77。 但179二进制表示是
10110011
所以,不应该输出为-51,考虑到第1位被烧焦位。的-77 二进制表示是
11001101
这似乎有点次序颠倒。这是怎么回事?请有人建议。
你声称-77
的二进制表示是11001101
,但逆转是你的。 -77
的二进制表示是10110011
。
二进制10110011
无符号是十进制的179
。
二进制10110011
有符号是十进制的-77
。
您将超出范围的值179
分配到signed char
。理论上它可能是未定义的行为,但除了抛出一个错误之外,它将是一个非常差的编译器,它会在signed char
中放置除8位值以外的任何内容。
但是当打印时,它被解释为负数,因为b7被设置。
看起来像char
是系统上签名的类型。用于char
的有效范围将是[-128,127]
通过使用
char t = 179;
编译器使用2的179的补体(这是最有可能-77)和将该值分配给t
。
要积极,2的补负数您反转所有位之间转换,那么你加1
01001100(反转所有位)
01001101(加一)
也就是说77十进制
请注意,在许多系统上char
签署。因此,当您将179(int
类型)分配给char
时,此值超出char
范围,因此它是未指定的行为。
6.3.1.3符号和无符号的整数:
当与整数类型的值被转换为比其它_Bool另一个整数类型,如果该值可以通过新的类型来表示,它是不变的。否则,如果新类型是无符号的,则通过反复添加或减去一个无符号整数,而不是新类型中可以表示的最大值进行转换,直到该值处于新转换类型的范围内。 否则,新类型被签名并且其值不能被表示;结果是实现定义的或实现定义的信号被引发。
如果您更改类型为unsigned char
您的程序将正确执行。
还要注意的是char
,signed char
和unsigned char
3点不同的类型,不同int
和signed int
。 char
的签名是实现定义的。
起初你说“它是未定义的行为”,现在你说“它是未指定的行为”,既然C具有这些措辞的特定定义。正确的说法是*结果是实现定义的或实现定义的信号被提升*。 – ouah
http://en.wikipedia.org/wiki/Two%27s_complement – ouah
为了扩展上述评论,您所期望的二进制负数编码方案称为[sign and magnitude](http:// en .wikipedia.org/wiki/Signed_number_representations#Signed_magnitude_representation),它只是使用最高有效位作为符号位。这在实践中从未被使用过。负数通常用二补数表示法来实现。 – eigenchris
@eigenchris不,它不是符号大小,而是2的补码。今天很难找到1的补码或符号幅度系统。 -77和179的表示形式都是0xB3 –