关于原码,反码,补码的详细解答

目录

1.原码:

  2.反码:

3.补码:

在开始前,先问问大家一个问题,为什么一个字节的取值范围是-128~127呢?

1.原码:

原码是十进制数据的二进制表现形式,最左边是符号为,0表示正,1表示负。

比如56的二进制为0011100(第一个0为符号位,0111000为数据)

其中一个数字0或1表示一个比特位(bit),而一个字节为八个比特位,即0011 1000为1个字节(8个比特位)

按照定义,原码最大值与最小值分别为0111 1111(对应十进制数127)和1111 1111(-127)

一般来说原码对正数之间的计算没有什么问题,但在进行负数计算时出现弊端了。

注意:二进制的计算关键点是逢2进1,比如0000 0001+1=0000 0010

比如,

二进制:1000 0000->十进制:-0(即0)

加一后,对应十进制数应该为1对吧,但实际上是-1

二进制:1000 0001->十进制:-1(本来应为1)

依次类推,实际上都是取到相反数

为什么这样呢?

因为最左项的符号位,使得相加数均为负数由此为解决这个问题,我们引出了反码的概念。

  2.反码:

反码:为解决原码在负数计算失效的情况而出现的

计算规则:

·负数的反码,符号位不变,数据取反,即0变1,1变0

·正数的反码为其本身(即什么都不用变)

举个栗子:

十进制:-56->原码:1011 1000

其反码为:

十进制:-56->反码:1100 0111

则+1后为1100 1000,其对应十进制数为-55,结果与我们想要的一样。

那此时可能就有人问了,这个反码是否跟上面原码一样有什么缺点呢?

答案是,有,它的缺点是在进行跨0计算时会与正确的结果存在一个误差

比如:

-5的二进制数是1111 1010,

 6的二进制数是0000 0110,

二者则相加等于0000 0000(只取8位)转成十进制是0

而与我们想得到的结果(1)相差一个1。

那么为什么会出现这样的情况呢?

因为在反码中,十进制的0的二进制有两种表现形式,因此我们在进行跨0运算时总是多一位

关于原码,反码,补码的详细解答_第1张图片

那么我们接下来主要解决的就是将两种表现形式变成一种,这样就可以实现跨0 运算了

由此,我们引出了补码的概念

3.补码:

补码,与反码相比是错开一位的,比如(反码中对应-0)1111 1111改为对应-1,1111 1110改为对应-2,以此类推,最终实现了0对应一种二进制表现形式。

关于原码,反码,补码的详细解答_第2张图片

另外,这里还有一个小细节,就是-127的补码对应为1000 0001,这样就会空出一位,就是1000 0000,不过这也好理解,因为补码跟反码、原码是错开一位的,因此最后会多出一位,即-128无对应的原码和反码,不过由于计算机的数据存储与运算是通过补码进行的,所以并不影响计算机运行与工作。

关于原码,反码,补码的详细解答_第3张图片

由此我们就能更好的理解为什么一个字节的取值范围是-128~127了。

你可能感兴趣的:(#,语言基础,java)