首页 > 其他分享 >原码、反码、补码和移码详解

原码、反码、补码和移码详解

时间:2023-04-03 09:57:47浏览次数:43  
标签:反码 补码 负数 移码 127 正数 原码

计算入门

  • 原码:正数是其二进制本身;负数是符号位为1,数值部分取X绝对值的二进制。
  • 反码:正数的反码和原码相同;负数是符号位为1,其它位是原码取反。
  • 补码:正数的补码和原码,反码相同;负数是符号位为1,其它位是原码取反,未位加1。(或者说负数的补码是其绝对值反码未位加1)
  • 移码:将符号位取反的补码(不区分正负)

举个例子以一个字节8位说明:

编码10810(sbyte)-10810(sbyte)
原码 01101100 11101100
反码 01101100 10010011
补码 01101100 10010100
移码 11101100 00010100

 

 

一、为什么需要反码?

反码的作用就相当于数学中的负数。

对于小学生来说,会做的算术题是:5-3,但是不会做3-5。于是,我们上初中的时候,数学里就引进了一个新的概念:负数。引入负数之后,本来是减法的运算就可以变成加法来实现:

3-5=3+[-5]=[-2],中括号代表“负数”,“负数”就是我们人为给出的数学术语。

对于计算机来说,会做的算术题是:5+3,但是不会做3-5。于是,我们就在编码里引进了一个新的概念:反码。引入反码之后,本来是减法的运算就可以变成加法来实现:

3-5=3+[-5]=[-2],中括号代表“反码”,“反码”就是我们人为给出的计算机术语。

这里,你一定有一个疑问:为什么计算机只会做5+3,不会做3-5。这是因为在计算机的数字电路中只有加法器,没有所谓的“减法器”。不是说计算机厂商不会设计减法器,因为聪明的人既然发明了方法能够用加法来实现减法操作,那为什么还需要画蛇添足的弄一个减法器?

接着说:那么反码要怎么定义才能实现减法变加法的功能呢?聪明的人想的办法如下:

1.正数反码保持原码不变:3=[0_0000011]

2.负数最高位(正负符号位)外,全部取反(0变1,1变0):-5=1_0000101取反=[1_1111010]

于是3+[-5]=[-2]的计算过程为:

[0_0000011]+[1_1111010]=[1_11111101]

这样,这种反码方法就成功实现了目标!至于为什么,我想只有数学家能给出解释了。

二、为什么需要补码?

都是因为“0”这个特殊数字的存在。

先问你一个问题:0是正数还是负数?你肯定会说:0既不是正数也不是负数,这是我们初中学到的数学知识。这个回答没有问题,所以以后每次碰到0,人们都不会把它当正数或负数。

那么计算机呢?计算机不同于人脑,计算机在碰到任何数字之前只根据最高位的符号位来判断正负性,“0”表示正数,“1”表示负数。

前面我们推论了为何要用反码,那么用8位二进制反码表示的正数范围: +0 —— +127;负数范围: -127 —— -0。但是,其中有两个特殊的编码会出现:

[0_0000000]=+0 (反码)

[1_1111111]=-0 (反码)

其实,+0和-0代表的都是0。这样一来,“0”这个数字在计算机中的编码就不是唯一的了。对于计算机来说,这是绝对不行的,因为任何数字都只能有1个编码。

于是,聪明的人就做了这样一个决定:把0当成正数,也即+0,这样0的编码就变成:0_0000000。那8位二进制表示的正数范围仍然是: +0 —— +127。

但是,对于负数就必须要做调整,也即-0必须要让位---1_1111111这个编码不能表示-0。我们可以把负数整体向后“挪动1位”:只要将8位二进制表示的负数范围从:-127 —— -0变成:-128 —— -1,就能成功解决问题。

那么怎么整体挪动1位呢?方法就是反码+1。{1_1111111}编码就不再表示-0,而变成了-1。顺着推,最小的编码{1_0000000}就是-128。

我们给这个反码+1又人为的取了一个新的名字,叫补码。于是乎,补码的定义如下:

1.正数的补码保持原码不变:3={0_0000011}

2.负数先求反码,然后再加1:-5=[1_1111010]+1={1_1111011}

于是3+{-5}={-2}的计算过程为:

{0_0000011}+{1_1111011}={11111110}

至此,通过补码就成功解决了数字0在计算机中非唯一编码的问题,且也能实现减法变加法。

所以,在计算机的世界里,0是正数。这点和我们学的数学不一样。

{0_1111111}=+127 (补码)

{0_0000000}=+0 (补码)

{1_1111111}=-1 (补码)

{1_0000000}=-128 (补码)

负数最低位

(-1) + (-127) = [1000 0001] + [1111 1111] = [1111 1111]+ [1000 0001]= [1000 0000]

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]算出来的原码是[0000 0000], 这是不正确的)

使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127] ==  [  [1000 0000]补  ,   [0111 1111]补 ] == [-27, 27-1]

因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

参考:
https://www.jianshu.com/p/abbdae4f3841
https://zhuanlan.zhihu.com/p/105917577

标签:反码,补码,负数,移码,127,正数,原码
From: https://www.cnblogs.com/wxdlut/p/17282158.html

相关文章

  • 原码,反码,补码
    0为什么会出现原反补0.1如果用原码计算会出现的问题00000000==+010000000==-0如果+0+1=+1==00000001没有问题如果-0+1=+1!=10000001为-1出现问题如果-1+1=0!=10000010为-2出现问题所以用原码的方式计算负数的加减法,在十进制到二进制的逻辑......
  • 【C版本】静态通讯录与动态通讯录的实现,以及各自所存在的缺陷对比。(含所有原码)
    @​​TOC​静态版本通讯录前期思路与之前的扫雷以及三子棋的实现方式是一样的,创建两个源文件,一个用来测试,一个用来存放函数定义,再创建一个头文件,用来存放函数声明。接下来是......
  • 原码反码补码
    计算机存储的是数据的补码原码数据的二级制形式。例如123的原码:01111011无符号数:原码==反码==补码123原码:01111011123反码:01111011123补码:01111......
  • 原码、反码、补码
    一、位运算符(一)真值表位运算符作用于位,并逐位执行操作。“与”“&”、“或”“|”和“异或”“^"的真值表如下所示:pqp&qp|qp^q000000101111......
  • 随堂测补码
    修改界面:<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtml><html><head><metacharset="UTF-8">......
  • byte,short,int等类型的转换以及原理,原码,反码,补码
    理论:八个比特(Bit)称为一个字节(Byte),最大[11111111],即FF;两个字节称为一个字(Word,Short),最大[1111111111111111],即FFFF,两个字称为一个双字(Dword,Int),最大[1111111111111111......
  • 补码
    为什么补码等于反码+1-简书(jianshu.com)我们必须要了解的Java位运算(不仅限于Java)-陈咬金-博客园(cnblogs.com)......
  • 二进制表示:原码、反码、补码详解
    本文主要介绍计算机中二进制的表示方法,详细介绍了十进制转二进制的方法,以及原码、反码和补码的不同和应用。一、二进制的计算要进行二进制的表示,首先需要进行计算二进制......
  • 5.3.2_原补码的除法运算
    @目录一、介绍二、原码的除法运算(1)手算除法之十进制1.过程2.原理(2)手算除法之二进制1.过程2.原理(3)机器实现1.恢复余数法原理过程手算模拟总结2.加减交替法恢复余数法简化举......
  • 5.3.1_原补码的乘法运算
    @目录一、原码乘法运算(1)手算乘法1.十进制乘法2.二进制乘法3.一些问题(2)机器实现1.案例2.确定符号位3.绝对值相乘的机器实现4.补充说明(3)手算模拟原码一位乘法二、补码乘法运......