概念:
原码:其实就是真实数值的二进制表示方法(只不过根据计算机不同字长表示需要不同个数的0)
比如正整数6在字长为8的计算机中表示的原码 0 000 0110 其中第一个数字为符号位,为零代表正数,第一个数字为1则为负数(-6的原码就表示为1 000 0110)
假设是在16字长的计算机中6的原码就表示为0 000 0000 0000 0110
反码:若为正数则和原码相同,若为负数则符号位不变,其它各位取反(若为1取反就是0,反之亦然)
比如6的反码为:0 000 0110
-6的反码为: 1 111 1001
补码:若为正数则和原码相同,若为负数则符号位不变,并将反码加1(即其它各位取反并将最低位加1)
加减计算:
- 在做补码加减法时,只需将符号位和数值部分一起参与运算,并且将符号位产生的进位丢掉即可
- 补码加法公式
[X+Y]补 = [X]补 + [Y]补 - 补码减法公式
[X-Y]补 = [X]补-[Y]补 = [X]补 + [-Y]补
其中:[-Y]补称为负补,求负补的办法是:对补码的每一位(包括符号位)求反,且未位加1.
假设字长为8的计算机byte类型所能表示的最大数是11111111,若再加1称为100000000(9位),但因只有8位,最高位1自然丢失。又回了00000000,所以字长为8的二进制系统的模为2^8。
加减计算规则参考原文:https://www.jianshu.com/p/abbdae4f3841
移位计算:
左移与右移都先转换成补码形式
左移:高位丢弃,低位补零 例:0111 1111 左移两位得到 1111 1100 从127变成了252
右移:低位丢弃,高位补符号位 例:0111 1111 右移两位得到 0001 1111 从127变成了31
从补码再转回原码方法:若为正数(第一位为0)则补码与原码相同,若为负数(第一位为1)则对这个数再次取补码即可
与,或,异或,非运算:
位与( & ):第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n位也为1,否则为0
5&3 =1
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
-------------------------------------------------------------------------------------
1转换为二进制:0000 0000 0000 0000 0000 0000 0000 0001
位或( | ):第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n位也为1,否则为0
5|3 = 7
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
-------------------------------------------------------------------------------------
7转换为二进制:0000 0000 0000 0000 0000 0000 0000 0111
位异或( ^ ):第一个操作数的的第n位于第二个操作数的第n位 相反,那么结果的第n位也为1,否则为0
5^3 = 6
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
-------------------------------------------------------------------------------------
6转换为二进制:0000 0000 0000 0000 0000 0000 0000 0110
位非( ~ ) :(位非是一元操作符)
~5 = -6
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
-------------------------------------------------------------------------------------
-6转换为二进制:1111 1111 1111 1111 1111 1111 1111 1010
参考:https://blog.csdn.net/xiaochunyong/article/details/7748713
至于为何要用补码做计算,是因为计算机为了简化电路只保留了加法器,现代计算机都以补码形式存储数据,而补码可以让加减法都使用加法电路实现