【原码—反码—补码】计算机进制浅谈领会

目录

前言

原码、反码、补码的基本计算

一、原码

二、反码

三、补码

为何要将 原码-->反码--> 补码?

一、原码的减法计算(错误值问题)

二、反码的减法计算(+- 0 问题)

三、补码的减法计算(解决0符号两编码问题)

四、byte 的最低值比最高值多表示一个

总结

进制之间的转换



链接:2 ~ N ... 进制的计算

前言

因为一般计算机没有减法算法,减法的硬件架构昂贵,研究人员们就通过原码、反码、补码的计算方式去实现通过加法去运算减法。

原码、反码、补码的基本计算

一、原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号位。
其余位表示真值. 比如如果是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] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

总结

  1. 正数的原码、反码、补码是其本身(相同),最高符号位是 0 ,除最高位其后是真值。
  2. 负数则是以补码形式出现:负数的二进制就是正数二进制的【~ 取反 + 1】,反转:负数的二进制转正数 【- 1 ~ 取反】

进制之间的转换

规则:十进制 除以 进制数 取余法:(1)被除数 除以 除数 等于 商 并取得余数,(2)并再用商 除以 除数,(N~)以此类推 ... ...,直到商小于除数并把这个商用做余数。(结果)得到每一位余数的顺序将其反转后,得到的就是转换后的进制。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚妄狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值