一、回顾char的数值范围

01111111  127    2的7次方-1  即 10000000-1
...
00000011  3
00000010  2
00000001  1

00000000  0     -------------------------

11111111  -1
11111110  -2
11111101  -3
...
10000000  -128  -2的7次方

为什么在计算机的有符号数中11111111代表-111111110代表-2

答:因为计算机是使用补码来表示负数的,对于有符号char来说,
在计算机看来11111111就是-111111110就是-210000000就是-128


二、补码

计算机存储数据时,是以补码形式存储的:

  • 正数的补码:就是自己,也就是说计算机存储正数补码时,存储的就是正数本身
  • 负数的补码:绝对值 取反 +1,计算机存储负数时,在计算机中这个补码就代表这个负数

1. -1 在计算机中存储时,存储的补码是多少

我们假设为char型

00000001  |-1|
11111110  取反
11111111  加1

存储的-1补码为11111111

2. -2 在计算机中存储时,存储的补码是多少

我们假设为char型。

00000010  |-2| ~
11111101  +
          1
11111110

存储的-2补码为11111110

3. 得到了某个补码后,计算真实数

比如补码为11101100,假设还是为char类型,那么它所代表的是?

                取绝对值            取反  +1
计算补码:-?————————————————> ? ——————————————>  11101100
反推:
            -1  取反             加上(符号 -)
11101100 ————————————————> ?————————————>  -?

            -1 取反                   加上-
11101100 ——————————>00010100(20)———————————> -20

4. 计算机存储补码有什么好处

提问:同一个有符号数的 正数补码 + 负数补码 = ?

为了描述的方便,我们还是以char型来讲解

  • 5的补码:00000101
  • -5的补码:11111011

计算机其实就是将5-5的补码相加

 5  00000101
-5  11111011
   100000000
    00000000  char型只允许8bit有效,将溢出位去掉,结果为0

这不就是实现了同一个数的正负数相加等于0吗,这就存储补码的好处,正数补码 + 负数补码 = 0

对于人来说,5+(-5)=0属于数学规则,人们只要一看到这个表达式就知道结果为0
但是对于计算机来说不可能通过感觉来计算,它必须要有具体的实现规则


5. 有符号、无符号赋值例子

例子:

int a= -20,unsgined int b = a;

请问ab各自代表的十进制数是多少?

请一定要理解这个例子,我们后面讲自动类型转换时,会牵涉到这个例子。

a所代表的十进制数是多少?计算机存放-20时,存放的是-20的补码

         取反 + 1               补码:实际存储的内容
|-20|  ——————————————>11111111 11111111 11111111 11101100

由于a的类型为int(有符号),数据的最高位为符号位,最高位为1,表示它是负数的补码,
因此11111111 11111111 11111111 11101100所表示的十进制数是一个负数,通过反推可知,为-20

unsgined int b = a;

通过初始化,a中的11111111 11111111 11111111 11101100被复制到了b中,
还是那个二进制数,但是由于b的类型为unsgined int,因此会以unsgined int去解释这个数

此时最高位不再是符号位,整个二进制数就是正数的补码,因此这个二进制数代表的是一个非常大的正数4294967276

再次总结,对于同一个二进制数来说,由于有符号与无符号的区分,它所代表的十进制数可能会截然不同