为什么char能表示-128

以前一直不太理解为什么8位的char能表示-128,经过学习,总结如下:

8位的char能表示的八位二进制包括:

0000 0000 - 0111 1111 : 0 - 127

1000 0000, 1000 0001 - 1111 1111 : -128,-127 - -1

C语言中-128的补码是1000 0000,下面来解释一下原因。由于-128的原码用8位无法表示,所以必须扩展表示(这里以扩展到16位为例),然后对16位的原码计算出16位的反码和补码,最后对16位的补码作低8位的截断,截断的低8位的值就是-128的补码了。

// 8位所能表示的  原码 的范围-127到+127
// 8位所能表示的  反码 的范围-127到+127
// 8位所能表示的  补码 的范围-128到+127

// C语言中-128的补码是1000 0000
// 由于-128的原码的数值部分已经有8位,所以符号位需要扩展
// 以扩展到16位为例 

// -128  原码 1000 0000 1000 0000
// -128  反码 1111 1111 0111 1111
// -128  补码 1111 1111 1000 0000

// 由于char只有8位,对-128的补码截断低8位,便是:1000 0000

// -129  原码 1000 0000 1000 0001
// -129  反码 1111 1111 0111 1110
// -129  补码 1111 1111 0111 1111

// vc6.0
int main(int argc, char* argv[])
{
    char ch = -129; // warning C4305: 'initializing' : truncation from 'const int ' to 'char '
    char ch2 = -128; // no warning
    return 0;
}

注意:由于char能表示的范围是:-128~127,如果将-129赋给char,编译的时候是会产生warning的,并会截断,截断后的值是0x7f(127)。

引申:反码和补码的由来

和计算机的设计有关,计算机里只有加法,其它的减法、乘法和除法都是转换为加法来处理的。为了能正常的处理加法,需要反码和补码的存在。

以7-5=7+(-5)为例,

 0_0000111(7的原码)
 1_0000101(-5的原码)
 1_0001100(加和的原码:-12)

 0_0000111(7的反码)
 1_1111010(-5的反码)
10_0000001(加和的反码:1)

 0_0000111(7的补码)
 1_1111011(-5的补码)
10_0000010(加和的补码:2)

从以上来看,只有补码的结果正确。

你可能感兴趣的:(c,c)