目录
前言
因为一般计算机没有减法算法,减法的硬件架构昂贵,研究人员们就通过原码、反码、补码的计算方式去实现通过加法去运算减法。
原码、反码、补码的基本计算
一、原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号位。
其余位表示真值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
取值范围
[0111 1111 , 1111 1111]
127,-127
二、反码
正数的反码是其本身。
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
三、补码
正数的补码就是其本身。
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
为何要将 原码-->反码--> 补码?
现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:
[+1] = [00000001]原 = [00000001]反 = [00000001]补
但是对于负数:
[-1] = [10000001]原 = [11111110]反 = [11111111]补
我们知道, 根据运算法则减去一个正数等于加上一个负数 ,即: 1-1 = 1 + (-1) = 0 。
所以机器只有加法而没有减法,这样计算机运算的设计就更简单了。
一、原码的减法计算(错误值问题)
计算十进制的表达式: 1-1=0
1 - 1 = 1 + (-1) =
[00000001]原 + [10000001]原 = [10000010]原 = -2
为了解决原码做减法的问题, 出现了反码
二、反码的减法计算(+- 0 问题)
1 - 1 = 1 + (-1) =
[0000 0001]原 + [1000 0001]原 =
[0000 0001]反 + [1111 1110]反 =
[1111 1111]反 = 转[1000 0000]原= -0
发现用反码计算减法,结果的真值部分是正确的。
而唯一的问题其实就出现在"0"这个特殊的数值上, 虽然人们理解上+0和-0是一样的,但是0带符号是没有任何意义的, 而且会有 [0000 0000] 原 和 [1000 0000]原 两个编码表示0。
补码的出现, 解决了0的符号以及两个编码的问题
三、补码的减法计算(解决0符号两编码问题)
1 - 1 = 1 + (-1) =
[0000 0001]原 + [1000 0001]原 =
[0000 0001]反 + [1111 1110]反 =
[0000 0001]补 + [1111 1111]补 =
[0000 0000]补 = 转[0000 0000]原 (正数的原码其本身等于 == 反码和补码)(所以正数不需要转换成原码)
(负数的反码补码才需要逆向转原码)
这样 0 用 [0000 0000] 表示,,而以前出现问题的 -0 则不存在了,
所以 byte 就可以用 [1000 0000] 表示 -128
四、byte 的最低值比最高值多表示一个
(-1) + (-127) =
[1000 0001]原 + [1111 1111]原 =
[1111 1110]反 + [1000 0000]反 =
[1111 1111]补 + [1000 0001]补 = [1000 0000]补
- (-1) + (-127) 的结果应该是 -128,在用补码运算的结果中, [1000 0000] 补 就是等于 -128,但是注意因为实际上是使用以前的 -0 的补码来表示 -128,所以 byte 中 -128 并没有原码和反码表示 (对 -128 的补码表示 [1000 0000] 补算出来的原码是 [0000 0000] 原, 这是不正确的)。
- 使用补码, 不仅仅修复了 0 的符号以及存在两个编码的问题,而且还能够多表示一个最低数, 这就是为什么 8位二进制,使用原码或反码表示的范围为[-127, +127],而使用补码表示的范围为 [-128, 127]。
- 所以机器使用补码进行运算及表示, 所以对于编程中常用到的32位int类型,可以表示范围是: [-2的31次方, 2的31次方 - 1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.
总结
- 正数的原码、反码、补码是其本身(相同),最高符号位是 0 ,除最高位其后是真值。
- 负数则是以补码形式出现:负数的二进制就是正数二进制的【~ 取反 + 1】,反转:负数的二进制转正数 【- 1 ~ 取反】
进制之间的转换
规则:十进制 除以 进制数 取余法:(1)被除数 除以 除数 等于 商 并取得余数,(2)并再用商 除以 除数,(N~)以此类推 ... ...,直到商小于除数并把这个商用做余数。(结果)得到每一位余数的顺序将其反转后,得到的就是转换后的进制。