关于java:深入理解计算机中的原码补码反码

51次阅读

共计 2139 个字符,预计需要花费 6 分钟才能阅读完成。

根本数据类型



计算机底层存储数据时应用的是二进制数字,然而计算机在存储一个数字时并不是间接存储该数字对应的二进制数字,而是存储该数字对应二进制数字的补码。所以接下来咱们须要来理解一下 原码 反码 补码

  • 机器数:一个数在计算机的存储模式是二进制数,咱们称这些二进制数为机器数,机器数是有符号,在计算机中用机器数的最高位寄存符号位,0 示意负数,1 示意正数。
  • 机器数的真值:因为带有符号位,所以机器数的模式值不等于其真值,以机器数 1000 0111 为例,其真正示意的值为 -7,而模式值为 135。将带符号的机器数的真正示意的值称为机器数的真值。

原码

原码 的示意与机器数真值示意的一样,即用第一位示意符号,其余位示意数值,例如的十进制的的正负 1,用 8 位二进制的原码示意如下:

【+1】= 原:[0000 0001]

【-1】= 原:[1000 0001]


反码

反码 的示意办法为:

  • 负数的反码是其原码自身。
  • 正数的反码是在其原码的根底上,符号位不变,其余各位取反。

【+1】= 原:[0000 0001] = 反:[0000 0001]

【-1】= 原:[1000 0001] = 反:[1111 1110]


补码

补码 的示意办法为:

  • 负数的补码是其原码自身。
  • 正数的补码是在其原码的根底上,符号位不变,其余各位取反后加 1(即在反码的根底上加 1)。

【+1】= 原:[0000 0001] = 反:[0000 0001] = 补:[0000 0001]

【-1】= 原:[1000 0001] = 反:[1111 1110] = 补:[1111 1111]


数据在计算机中的存储模式

计算机理论只存储补码,所以原码转换为补码的过程,也能够了解为数据存储到计算机内存中的过程:

在原、反、补码中,负数的示意是截然不同的,而正数的示意是不雷同的,所以对于正数的补码来说,咱们是不能间接用进制转换将其转换为十进制数值的,因为这样是得不到计算机真正存储的十进制数的,所以应该将其转换为原码后,再将转换失去的原码进行进制转换为十进制数。(机器数蕴含符号位)

pingxiong:说到这你应该懂得了计算机底层是如何存储数据的了吧,但咱们不能止步于此,咱们还应该晓得为什么要这么存储?


问题:为何应用原码、反码、补码

咱们下面说过,原码、反码、补码的示意对于负数来说都是一样的,而对于正数来说,三种码的示意确是齐全不同的,那大家是否会有个疑难:如果原码才是咱们人类能够辨认并用于间接计算的示意形式,那为什么还会有反码和补码?计算机间接存储原码不就完事了?

在解决这些问题前,咱们先来理解计算机的底层概念,咱们人脑能够很轻松的晓得机器数的第一位是符号位,但对于计算机根底电路设计来说判断第一位是符号位是十分难和简单的事件,为了让计算机底层设计更加简略,人们开始摸索将符号位参加运算,并且采纳只保留加法的办法,咱们晓得减去一个数,等于加上这个数的正数,即:1-1 = 1 + (-1) = 0,这样让计算机运算就更加简略了,并且也让符号位参加到运算中去。

1. 应用原码运算

计算十进制表达式:1-1 = 0;

1 – 1 = 1 + (-1)

= 原:[0000 0001] + 原:[1000 0001]

= 原:[1000 0010] = -2

如果用原码示意,让符号位也参加计算,对于减法来说,后果是不正确的。这也是计算机外部在存储数据时不应用原码的起因,为了解决这一问题,呈现了反码。


2. 应用反码运算

计算十进制表达式:1-1 = 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。为了解决这一问题,呈现了补码。


3. 应用补码运算

1 – 1 = 1 + (-1)

= 原:[0000 0001] + 原:[1000 0001]

= 补:[0000 0001] + 补:[1111 1111]

= 补:[0000 0000] = 原:[0000 0000] = 0

这样 0 用 [0000 0000] 示意,而以前呈现问题的 - 0 则不存在了,而且人们还发现能够用 [1000 0000] 示意 -128,-128 的推算过程如下

(-1) + (-127) = -128

= 原:[1000 0001] + 原:[1111 1111]

= 补:[1111 1111] + 补:[1000 0001]

= 补:[1000 0000]

留神:因为实际上是应用以前的 - 0 的补码来示意 -128,所以 -128 并没有原码和反码示意,只有补码是[1000 0000],其十进制数值就为 -128。


因为补码能多存储一个 -128,而且在计算机底层中存储的是补码,所以在计算机中一个 8 位的二进制数的存储范畴是用补码示意的[-128,127],而不是用原码或反码示意的[-127,127]。这也能够解释为什么计算机中一个字节的取值范畴是[-128,127]。

这样也可能答复咱们开始提出的问题了,原码、反码、补码的应用,是人们为了让符号位能参加运算并让计算机底层运算更加简略而设计进去的数据存储示意形式。


更多精彩内容敬请关注微信公众号:【平兄聊 Java】

正文完
 0