1.为什么要了解补码?
首先来看五个问题:
1.int型变量所能存储的数字范围是?
2.最小整数的二进制代码是什么?
3.数字超过最大正整数会怎么样?
4.最大整数的二进制代码是多少?
5.int形变量和char变量是如何相互赋值的?
补码的内容以前在Java中了解过一点点,当时有点迷糊,希望这次会好点,这个我目前不是很理解这本书为什么将这个内容写的这么靠前,这些东西接近于底层相对来说可能会难理解一点点,但是仅仅只是一点点!
2.什么是原码和反码?
原码:
原码也叫做“符号绝对值码”,最高位0表示正,其余的二进制数表示绝对值的二进制数
0101表示5,10101表示-5
反码:
反码就是所有的位数都取反1变成0,0变成1
目前简单的了解一下原码和反码就行,
3.补码的两个核心问题
(1)十进制转换为二进制补码
正整数补码和原码相同
负整数补码求法:先求该负数绝对值的二进制数,然后将所有的位数取反在位数不够的情况下加1,直到满足位数要求
比如int的-6,绝对值是6,int占32位,则6的二进制代码是
0000 0000 0000 0000 0000 0000 0000 0110
所有位数取反
1111 1111 1111 1111 1111 1111 1111 1001
再在末位加1
1111 1111 1111 1111 1111 1111 1111 1010
此时就是得到了-6
注意0的补码是唯一的是0
3.二进制补码转换为十进制
已知一个数的补码,求源码的操作就是对该补码在进行求补码
(1)如果最高位是0,则表明是正整数,原码和补码相同,比如
0000 0000 0000 0000 0000 00000 0000 1111
这个数的最高位就是0,表明这个数是正整数,此时原码和补码相同,将这个直接转换为十进制就是15
(2)如果最高位是1,则表明是负整数,此时原码为:将所有位都取反,然后末位加1,此时会得到无符号形的二进制,所有位数都是数字位,没有符号位所以算出来一定是一个正整数,这个正整数就是该补码对应的十进制数。比如:
1111 1111 1111 1111 1111 1111 1111 1000
这里的最高位就是1,负数,所有数字取反:
0000 0000 0000 0000 0000 0000 0000 0111
末位加1
0000 0000 0000 0000 0000 0000 0000 1000
转换为十进制就是8,补码就是-8
(3)如果全是0,则对应的十进制就是0
4.数据的存储范围
(1)int数据的存储范围
我们都知道int变量占4字节,一字节就是8位,int占32位,则int能存储的最大值为
0111 1111 1111 1111 1111 1111 1111 1111
就是2147483647
如果此时加一个1会发生什么呢?
就是成为:
1000 0000 0000 0000 0000 0000 0000 0000
最左边是1,此时这个数就会变成负数-2147483648
根据前面学到的知识来验证一下:
将所有数字取反
0111 1111 1111 1111 1111 1111 1111 1111
末位加1,这个时候会惊奇的发现,居然和之前的数一样了,此时就是:
1000 0000 0000 0000 0000 0000 0000 0000
0111 1111 1111 1111 1111 1111 1111 1111就是2147483647
末位加1之后就是
1000 0000 0000 0000 0000 0000 0000 0000、
即2147483647+1 = 2147483648,然后第一位数是1,此时表示这个数就是负数值为-2147483648
写一点点的代码来验证一下:
#include <stdio.h>
int main(void){
int a = 2147483648;
printf("%d\n", a);
return 0;
}
运行结果如下:
D:\code\C\st03.exe
-2147483648
Process finished with exit code 0
很好的验证了上面,此时我们就会想到如果给这个21474836648再加一个1之后会发生什么:
#include <stdio.h>
int main(void){
int a = 2147483649;
printf("%d\n", a);
return 0;
}
结果:
D:\code\C\st03.exe
-2147483647
Process finished with exit code 0
这时候会惊奇的发现还是这个数,这时候就要想一下,这是为什么呢
此时的原码就是:
1000 0000 0000 0000 0000 0000 0000 0001
但是在计算机的眼中这个就是一个补码
第一位的数字是1,表示负数,1000 0000 0000 0000 0000 0000 0000 0000表示-2147483648,在进行加1之后就会成为-2147483647,直到再加一轮之后会重新从0开始;
(2)int和char是如何互通的
一般情况下int存储回是2、4、8字节,但是字符只有1字节,即8位;这时候所能存储的最大的正整数二进制0111 1111 十进制就是128,负数就是-128;
如果将int的258存入int会是多少呢?
首先将这个转换为二进制就是 0000 0000 0000 0000 0000 0001 0000 0010
将这个存入char就是只会存储0000 0010此时就是2
写代码来验证一下
#include <stdio.h>
int main(void){
char a = 258;
printf("%d\n", a);
return 0;
}
运行结果如下
D:\code\C\st03.exe
2
Process finished with exit code 0
这时候我们就是直到,在一般情况下,我们将这int赋值给char的时候int的值不要超过127
一般情况下,什么类型的数据就采用什么变量
5.ASCII
这个这里我就直接放一张ASCII表,现阶段知识会查表就行了,这个表百度的
自我感觉原码补码可以更好地理解计算机对数字的存储原理,还是挺有用的