之前一直搞不清这几个概念的区别联系
机器数
指的是十进制数的二进制表示,正负号用计算机字长的最高位表示,“+”用0表示,“-”用1表示
如计算机字长为8:
10 的机器数为: 000001010
-10 的机器数为: 100001010
真值
是相对机器数来说的,是机器数的十进制表示
假如计算机字长为8:
机器数为: 00001010 真值为: 10
机器数为: 10001010 真值为: -10
原码、反码、补码都属于机器数,是机器数的三种编码方式
原码的也就是待编码的机器数,即等于原来的机器数,如:
机器数为: 00001010 原码为: 00001010
机器数为: 10001010 原码为: 10001010
反码:
如果机器数的真值是正数,则 反码 = 原码
如果机器数的真值是负数,则 反码 = 原码的二进制位取反(除符号位)
真值: 10 原码为: 00001010 反码为: 00001010
真值: -10 原码为: 10001010 原码为: 11110101
补码:
如果机器数的真值是正数,则 补码 = 原码
如果机器数的真值是负数,则 补码 = 原码的二进制位取反(除符号位) + 1, 即反码 + 1
真值: 10 原码为: 00001010 反码为: 00001010
真值: -10 原码为: 10001010 原码为: 11110110
为啥要原码、反码、补码呢,存在的意义是啥?
存在即合理,因为计算机是不会通过真值来加减法的,只能转换为二进制,如:
1、要想求 10 – 5 的值,计算机是把公式表示为 10 + (-5),也就是两个数的加法
真值: 10 原码为: 00001010
真值: -6 原码为: 10000110
假设直接通过两个原码直接相加的结果肯定是不对的,这时借助反码:
真值: 10 原码为: 00001010 反码: 00001010
真值: -6 原码为: 10000110 反码: 11111001
两个反码相加为: 00000001 00000011
再转成原码为: 00000100 (反码相加进位的话要加1)
真值为: 4
2、举个补码的例子:
看起来反码就能满足加减运算了,可是为什么还要补码呢,看下面:
真值: 2 原码为: 00000010 反码: 00000010
真值: -2 原码为: 10000010 反码: 11111101
两个反码相加值为: 11111111
转成原码为: 10000000
真值为: -0
这样真值貌似也没啥问题,0的原码就可表示为: 10000000 和 00000000,明显就是不靠谱的,因此补码:
真值: 2 原码为: 00000010 反码: 00000010
真值: -2 原码为: 10000010 反码: 11111110
两个反码相加值为: 1 00000000 (补码相加进位的话要舍弃)
转成原码为: 00000000
真值为: 0
于是0的原码只能为 00000000, 这里 10000000 可以作为 -128 的原码,完美~
反码、补码背后的原理我看了好几天还是没搞懂,后面有空再看吧:
目前网上有以下几种对加减运算的理解:
1、利用同余数的特点,将进行加减法的两个值等价替换
https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html#!comments
2、利用二进制的特点,认为负数可以直接被表示,通过判断结果的正负值来调整计算公式
http://www.ruanyifeng.com/blog/2009/08/twos_complement.html
3、通过取模运算+负数等价替换来实现
https://blog.csdn.net/mkr67n/article/details/114701908
4、也是通过取模运算,只不过负数是通过拍脑门儿设置的
https://www.zhihu.com/question/30395946?sort=created