原码 反码 补码

原码、反码、补码 原码:简单但有两个零。反码:解决了一部分问题,但仍有两个零。补码:最常用、最有效,只有一个零,简化了计算机的加减法运算。计算机内部广泛使用补码表示有符号整数,因为它简化了硬件设计和运算处理。了解这些概念有助于理解计算机的底层运算机制和一些算法的实现原理。 阅读详情

原码 反码 补码

对于 原码、反码、补码的学习记录
对于概念的描述也是基于个人理解做出的易于理解的表达方式,没有使用更严谨的数学公式定义

只针对整数
只针对加法

个人是从高位为符号位+低位为数值位的角度去理解的
但是不引入符号位这个概念也完全可以理解这三个概念,那就是另一种表述了,没有深入了解

非科班出身,足够个人使用的个人理解,可能根本原理上会有理解错误,如有错误希望有大佬指正

1.机器数和真值

1.1 机器数

数字在计算机中的二进制表示形式,有以下两个特点

  1. 具有符号位,即二进制中的最高位也就是最左边的一位表示符号, 0为正数, 1为负数(这是单符号位,还有双符号位不考虑)
  2. 其大小受字节长度限制

例如, 在 Java 的 byte 类型(1个字节Byte,8个比特bit)中

1 = [0000 0001] -1 = [1000 0001]

1.2 真值

真值就是机器码对应的真正的值,可以简单理解为使用正负号代替符号位

1 = [0000 0001] 真值为 +000 0001
-1 = [1000 0001] 真值为 -000 0001

2.原码

2.1 定义

一个数的原码为符号位加上真值的绝对值
即最高位为符号位,剩余位(数值位)为真值绝对值
.
原码中 0 会出现两种表示方式 1000 0000 和 0000 0000 即 -0,+0

原码是人可以直观理解的表示方式

以 Java 的 byte 类型(8bit,最高位为符号位,剩余7位为数值位)来说

原码取值范围为 -127 ~ 127, 存在符号位也参与计算, 0000 0000 和 1000 0000 只能都指向 0

1 = [0000 0001]: 正数,最高位为0, 数值位为1(真值1的绝对值)的二进制 000 0001
-1 = [1000 0001]: 负数,最高位为1, 数值位为1(真值-1的绝对值)的二进制 000 0001

2.2 加法运算

一般计算机中只有加法器而没有减法器,若设置单独的减法器则需要考虑结果的符号等一系列其他问题
为了简化设计,最简单的思路就是把减法转换为加法

1 + 1 = [0000 0001]原 + [0000 0001]原 = [0000 0010]原 = 2
-1 + (-1) = [1000 0001]原 + [1000 0001]原 = [1 0000 0010]原 = -2 // 溢出了
-1 + (-2) = [1000 0001]原 + [1000 0010]原 = [1 0000 0011]原 = -3 // 溢出了
-1 + 1 = [1000 0001]原 + [0000 0001]原 = [1000 0010]原 = -2
-1 + 2 = [1000 0001]原 + [0000 0010]原 = [1000 0011]原 = -3
-0 + 0 = [1000 0000]原 + [0000 0000]原 = [1000 0000]原 = -0

可以看到, 正数相加和负数相加是没问题的,而正数+负数则会出现问题

其实原码也是可以通过一系列的运算规则来得到正确的结果的,但是需要额外判断符号位、溢出等情况,这样一来设计复杂程度将提高很多

3.反码

3.1 定义

正数反码是其自身
负数反码为原码的符号位不变, 数值位按位取反

8位二进制反码取值范围为 -127 ~ 127, 存在符号位也参与计算但需要循环进位, 0000 0000 = +0 1000 0000 = -0

1 = [0000 0001]原 = [0000 0001]反
-1 = [1000 0001]原 = [1111 1110]反

3.2 加法运算

反码的加法涉及到一个 循环进位 的概念
简单理解就最高位即符号位计算时如果发生进位则需要将进位送到最低位再次相加
加法运算后结果仍为反码,但如果符号位为0则可以直接当做原码

1 + 1 = 
        0000 0001  // 原/反
      + 0000 0001  // 原/反
      ------------
      = 0000 0010  = 2 // 符号位为0为正数,直接当原码

-1 + 1 =
         1000 0001  // 原
       + 0000 0001  // 原
       ------------
     =   1111 1110  // 反
       + 0000 0001  // 反
       ------------
     =   1111 1111  // 符号位为1为负数,仍为反码
     =   1000 0000 = -0

-1 + (-1) =
            1000 0001  // 原
          + 1000 0001  // 原
          ------------
        =   1111 1110  // 反
          + 1111 1110  // 反
          ------------
        = 1 1111 1100  // 符号位进位了
        =   1111 1101  // 循环进位 符号位为1为负数,仍然是反码
        =   1000 0010 = -2

-1 + 2 =
         1000 0001  // 原
       + 0000 0010  // 原
       ------------
     =   1111 1110  // 反
       + 0000 0010  // 反
       ------------
     = 1 0000 0000  // 符号位进位了
     =   0000 0001 = 1 // 循环进位,符号位为0为正数,直接就是原码

-0 + 0 =
         1000 0000  // 原
       + 0000 0000  // 原
       ------------
      =  1111 1111  // 反
       + 0000 0000  // 反
       ------------
      =  1111 1111  // 结果仍然是反码
      =  1000 0000 = -0

0 + 0 =
        0000 0000 // 原/反
      + 0000 0000 // 原/反
      ------------
     =  0000 0000 = +0 // 原/反

可以看到,反码的运算可以满足减法变换为加法,但是运算规则较为复杂(当前少量设备是基于反码进行运算的,没有深入了解)
仍然不能忽略 +0 和 -0

4.补码

4.1 定义

补码的定义使用了模和同余的概念。
正数的补码即为原码。
负数的补码等于模 + 真值,其中模 = 2数值位数+1(也即可以表示数据的数量,双符号位(00为正,11为负)的同样遵循该方式)

根据定义,可以得到一个结论 负数补码 = 真值 + 模 -> 负数补码 = 模 - 真值绝对值

补码的意义是 按照这样一种编码规则(也就是表示正数、负数和零的约定),可以无需额外操作把减法运算变成加负数形式的加法运算
从而在直接省略减法器的同时简化加法器的设计

  • 1.根据定义进行负数补码计算

对于Java的byte类型, 数值位数=7,则模的值为 27+1 = 256, 即byte类型可以容纳的总数据量

256 = [1 0000 0000]原
-1 = [1000 0001]原 真值 = [-000 0001]
-2 = [1000 0010]原 真值 = [-000 0010]

256 + (-1) =
            1 0000 0000   // 模256 1 0000 0000
           -   000 0001   // 真值     -000 0001
           -------------
              1111 1111   // -1的补码

256 + (-2) =
            1 0000 0000   // 模256 1 0000 0000
           -   000 0010   // 真值     -000 0001
           -------------
              1111 1110   // -2的补码
  • 2.常用的一种通过反码计算负数补码的方法

负数补码 = 原码符号位不变数值位按位取反 + 1 = 原码的反码 + 1
负数原码 = (补码 - 1)后符号位不变数值位按位取反
.
在二进制中, 取反加一 和 减一取反 是等价的, 这点也是有证明的,有兴趣可以看一下
.
因此负数补码还原成原码的计算可以变换成
负数原码 = 补码符号位不变数值位按位取反 + 1 = 补码的反码 + 1
可以看到, 这个过程和原码->补码的计算过程是一样的
.
因此我们可以得出一个比较绕的结论

补码的补码就是原码或者补码和原码互为补码,严谨点说是 补码经过取反+1的操作后就是原码

这也是由 取模同余 这一概念决定的

-1 = 1000 0001  // 原码
     1111 1110  // 反码
     1111 1111  // 反码+1,即补码

-2 = 1000 0010  // 原
     1111 1101  // 反
     1111 1110  // 反码+1,即补码

注意 搜集资料时看到很多对反码的误解

虽然补码可以通过反码+1的方式计算
但并不代表反码就是原码和补码之间的过渡概念
也不代表补码是在反码的基础上发展而来
补码是根据取模同余设计出来的
反码和补码拥有同样的地位
反码也是有实际应用的,并不是补码的工具人
只是恰好 补码 = 反码 + 1,而且这样也方便理解,计算机计算补码也是这个方法(使用定义来计算补码需要减法运算,而补码就是为了干掉减法)
数学上有对于 补码 = 反码 + 1 的详细证明

4.1.1 模和同余

当两个整数除以同一个正整数,若得相同余数,则二整数同余
或者
两个整数 a,b,若它们除以整数 m 所得的余数相等,则称 a,b 对于模 m 同余
.
记作 a ≡ b (mod m)
读作 a 与 b 关于模 m 同余

需要注意 这里的余数应该使用 取模 运算获取,即计算中商应该向下取整

Java/C 等语言的 % 运算符向零取整,即使商更接近 0, 应该叫做取余
Python 等语言的 % 运算符向下取整,即使商更接近 -∞,是取模
.
两种取整方式在正数计算中没啥差别,但是负数计算结果就不一样了
因此Java/C的%运算符不能用于计算这个余数
Java中可以使用 Math.floorMod() 来进行取模运算

-23 mod 12 == 1  // 商≈-1.92, 向下取整=-2, 则余数为 -23 - (-2) * 12 = -23 + 24 = 1
-11 mod 12 == 1  // 商≈-0.92, 向下取整=-1, 则余数为 -11 - (-1) * 12 = -11 + 12 = 1
1 mod 12 == 1
13 mod 12 == 1
25 mod 12 == 1

则 -23,-11,1,13,25 都关于模 12 同余

这一点可以借助钟表表盘来理解
-23点 -11点 1点 13点 25点 在表盘上都是同一个位置,离12点都只有1格,只是顺时针/逆时针转了几圈的问题

这也是补码运算不需要关心符号位的原因
由于取模同余的性质,补码的取值范围(数轴)是圆形的,超限了也只是进入下一圈或上一圈
而原码和反码这类直线数轴的,超限后就完蛋了

虽然没有 -23点 的说法,理解含义即可

4.2 加法运算

4.2.1 同余加法

补码的加法运算其实是依据以下性质进行的同余加法

如果 a ≡ b (mod m), c ≡ d (mod m) 那么:
a ± c ≡ b ± d (mod m)

同样的乘法也有类似的性质
a * c ≡ b * d (mod m)

例如 对于byte类型 -1 ≡ 127 (mod 128) 1 ≡ 1 (mod 128)
则 -1 + 1 ≡ (127 + 1) (mod 128) ≡ 128 (mod 128); 即 -1 + 1 与 128 对于模 128 同余
而 128 mod 128 = 0; 则 -1 + 1 的值应该是byte类型取值范围(-128~127)中对128取模=0的数,也就是0

对于byte类型(8bit二进制数), -128 比较特殊

  1. 补码取值范围为 -128 ~ 127,存在符号位参与计算且不需用额外操作,也即补码的8位都可以作为数值位
  2. 解决了 +0 -0 的问题,因此相比于原码和反码空出了-0 即 1000 0000 的位置

这个多出来的 1000 0000 用来干啥呢?

  1. 根据 4.1 补码定义, -128的补码 = -128 + 256(模) = 128
    数学上128的二进制表示为 1000 0000

  2. 根据补码的连续性,8位二进制总共可以表示256个数字
    根据补码表,发现按顺序向下推进,-128处的补码正好也是 1000 0000

    原码反码补码真值
    0111 11110000 00000111 1111+127
    0111 11100000 00010111 1110+126
    原码-1…反码-1…补码-1…真值-1…
    0000 00000111 11110000 00000
    1000 00011111 11101111 1111-1
    原码-1…反码-1…补码-1…真值-1…
    1111 11111000 00001000 0001-127
    8位无法表示0111 1111(实际没有反码)1000 0000-128

上面两个情况计算出来的 -128 补码都是 1000 0000, 正好也是补码中多出来的位置
因此将 -128 的补码规定为 1000 0000 完全是合情合理的
而且 对应的原码在8bit下无法表示, 反码与 0 反码相同,所以 -128 没有原码和反码

可以发现,即使没有原码和反码,补码也是可以存在的
从这一点也可以得出,补码本质上是一个独立的概念,它不是以原码或者补码为基础存在的概念
原码、反码、补码三者是为了解决不同问题分别发展出来的三个独立概念
在数学上不能以概念出现的顺序来作为概念间关系的依据
感兴趣可以看看对数和指数两个概念的发展历史以及两者关系

4.2.2 补码加法

与反码的循环进位不同,补码的加法运算无需关注符号位的进位,可以将符号位的进位直接舍弃

+1 = [0000 0001]原 = [0000 0001]反 = [0000 0001]补
-1 = [1000 0001]原 = [1111 1110]反 = [1111 1111]补
+2 = [0000 0010]原 = [0000 0010]反 = [0000 0010]补
0 = [0000 0000]原 = [0000 0000]反 = [0000 0000]补

1 + 1 =
        0000 0001  // 原/补
     +  0000 0001  // 原/补
     -------------
    =   0000 0010 = 2

-1 + 1 =
         1111 1111  // 补
       + 0000 0001  // 原/补
       ------------
     = 1 0000 0000 // 溢出,直接抛弃
     =   0000 0000 = 0

-1 + 2 =
         1111 1111  // 补
       + 0000 0010  // 原/补
       ------------
     = 1 0000 0001  // 溢出,直接抛弃
     =   0000 0001 = 1

-1 + (-1) =
            1111 1111  // 补
          + 1111 1111  // 补
          ------------
        = 1 1111 1110  // 溢出,直接抛弃
        =   1111 1110  // 补
        =   1000 0001  // 之前提过 补码的补码就是原码
        =   1000 0010 = -2

5.总结

可以看到,计算机中大量应用了数学中的概念,可以说计算机就是在数学的基础上才发展起来的

只可惜没学好数学,更没学过计算机领域相关的数学概念,导致现在稍微想深入学习就得一点一点的慢慢抠

还有可能出现理解错误, 真是太难了

原码反码补码的概念,以及原码反码的表示形式 本文主要讲解计算机的原码, 反码和补码.的概念,以及原码反码的表示形式,以及原码反码补码之前如何相互转换,还有计算机中数字是怎么样存储的。 阅读详情

相关推荐

(25.08)Ubuntu20.04+ROS1复现FAST-LIO2

请确保在。

m0_69023437的博客 3994

原码, 反码, 补码 详解

原码, 反码, 补码 详解 本篇文章讲解了计算机的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法计算原码的减法. 论证部分如有不对的地方请各位牛人帮忙指正! 希望本文对大家学习计算机基础有所帮助! 一. 机器数和真值 在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念. 1、机器数 一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1. 比如,十进制中的

weixin_45839498的博客 2859

信贷审批中的那些坑:从零开始搭建风控策略体系的5个关键步骤

本文深入探讨了信贷审批中的风控策略体系搭建,从数据陷阱识别、规则冲突诊断到反欺诈攻防,提供了5个关键步骤的实战指南。重点解析了如何通过特征工程、决策树优化和模型可解释性技术,构建动态平衡的风控体系,有效降低逾期风险并提升审批效率。

weixin_29253711的博客 414

原码、反码和补码之间的转换

原码、补码和反码是用来表示有符号整数的三种表示方法,它们在计算机中常用于进行数值运算和存储。

qq_64928278的博客 2万+

LiteOS | 基于LiteOS的智慧农业案例实验分享

分享一个基于小熊派+LiteOS+华为云的案例实验(智慧农业)。 实验框图 相关模块简介 1、STM32L431RCT6 2、LiteOS LiteOS是华为开发的轻量级实时操作系统: LiteOS源码GitHub仓库链接: https://github.com/LiteOS/LiteOS 其源码一级目录结构如下: 其内核包括任务管理、内存管理、时间管理、通信机制、中断管理、队列管...

嵌入式大杂烩 5991

双目相机测距原理

普通双目相机具有如下特点:左右两个相机位于同一平面(光轴平行),且相机参数(焦距f)一致。其原理图如下:如图所示,P点为相应的物体位置,CL和CR为左右相机光心位置,PL和PR分别为左相机和右相机拍摄的P点成像结果。f为相机焦距,Z为物体距相机的深度距离,b为左右相机基线距离根据几何关系有:则相应的深度信息计算公式为:(1)其中XL-XR为视差。其余在两侧的情况同样可以用几何关系分析得到该表达式(1),即对于普通双目相机测距可以直接通过公式(1)得到深度结果。

doudou2weiwei的博客 4547

RSA加解密算法原理

本文译自http://www.muppetlabs.com/~breadbox/txt/rsa.html,作者Brian Raiter. This article is translated fromhttp://www.muppetlabs.com/~breadbox/txt/rsa.html. Theauthor isBrian Raiter. Thank Brian very mu...

以简为道 1931

别再调PID了!用MATLAB/Simulink给四旋翼无人机搭个ADRC控制器(附完整仿真模型)

本文详细介绍了在MATLAB/Simulink环境中为四旋翼无人机搭建ADRC控制器的完整流程,包括核心原理、Simulink建模、参数调试技巧及与PID控制的性能对比。ADRC通过扩张状态观测器(ESO)有效提升无人机在复杂扰动下的控制性能,特别适合四旋翼无人机这类强耦合系统。文章还提供了完整的仿真模型和工程实践问题解决方案。

weixin_26808439的博客 382

原码反码补码?看这篇就够了(保姆级讲解)

引入带符号数的表示方法是为了能够区分正数和负数,并且可以进行加、减等数学运算。在计算机中,常见的带符号数表示方法有原码、反码和补码。

aliyonghang的博客 1万+

随机优化 (Stochastic Optimization) 算法详解及案例分析

随机优化是一种用于处理包含随机变量的优化问题的方法。其目标是通过考虑随机变量的概率分布,找到一个在期望意义下最优的解。

闲人编程的博客 4184

华为OD机试真题:明日之星选举 (Java/Py/C/ C++/JS/GO)

华为OD机试(机考)双机位C卷 【明日之星选举】,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - 明日之星选举。

qq_45776114的博客 919

原码、反码、补码 详解!

一. 机器数和机器数的真值在学习原码,反码和补码之前, 需要先了解机器数和真值的概念。1、机器数一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用机器数的最高位存放符号,正数为0,负数为1。比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是0000 0011。如果是 -3 ,就是 100 00011。那么,这里的 0000 0011 和 1000 0011 就是机器数。2、机器数的真值因为第一位是符号位,所以机器数的形式值就不等于真正的数值。

chuixue24的博客 2万+

《大数据: Hive 交互命令和常用配置》

一、Hive 交互命令 1. 首先解决一个可能发生的问题 (log4 jar包冲突) 我这里解决方法就是删除一个,我删的是hive下的包 yexiang@hadoop1:<hive>$ hive SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/opt/soft/apache-hive-2.3.7-bin/lib/log4j-slf4j-impl-2.6.2.ja.

yexiang优快云的专栏 289

认识原码反码补码

原反补码

2202_75357702的博客 1734

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

原码、反码、补码的关系

在了解原码、反码和补码前需要先了解机器数和真值。 一、机器数和真值 1、机器数 一个数在计算机中的二进制表现形式称为这个数的机器数。在机器数中,一个数的最高位是符号位。例如:十进制中的 5 转为机器数就是 0000 0101,-5转为机器数就是 1000 0101。 2、真值 因为最高位是符号位,所以一个数的机器数并不能代表他的真值。例如1000 0101的最高位1代表负值,其真正的数值是-5,而...

宸宸的博客 3万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

原码、补码、反码的关系

一. 机器数和真值 在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念. 1、机器数 一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1. 比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。 那么,这里的 00000011 和 10000011 就是机器数。 2、真值 因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如.

leo187的博客 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

原码、反码及补码

任何存储于计算机中的数据,其本质都是以二进制码存储。计算机的运算器只有加法运算器。所以在计算机中没办法直接做减法。 从硬件的角度来说正数+正数、负数+负数都是可以通过加法器直接相加,只有正数加负数才算是减法。原码、反码及补码的产生过程就是为了解决计算机做减法和引入符号位的问题。

KEEP CODING 5203

原码、反码、补码的相互转换

首先,正数的原码,反码,补码都是相同的。 所以,这里讨论负数的原码,反码,补码的相互转化问题。 1、负数原码和反码的相互转化 负数原码转化为反码:符号位不变,数值位按位取反。 如: 原码 1100 0010 反码 1011 1101 负数反码转化为原码:符号位不变,数值位按位取反。 如: 反码 1011 1101 原码 1100 0010 2、负数反码和补码的相互转化 负数反码转化为补码:末尾...

qq_38236355的博客 5705

原码、反码、补码及用途

原码、反码、补码及用途 反码(Ones' Complement) 概念: 反码是通过对原码的数值部分逐位取反(0变1,1变0)得到的。 正数的反码和原码相同。 负数的反码是其原码除符号位外所有位取反。 补码(Two's Complement) 概念: 补码是反码加1得到的。 正数的补码和原码相同。 负数的补码是其反码加1。

热土程序园,利他愉己~ 2261

原码、补码和反码之间的转换

在开始之前首先明确3个概念: 1、正数的原码、补码和反码都是一样的。 2、计算机中是用补码来表示数字的二进制的。 3、二进制的最高位(第一位)是符号位,0表示正数,1表示负数。 下面以一些简单的例子来介绍原码、反码和补码。采用8位二进制来进行说明即:0000 0000; 原码 [12]原 = 0000 1100, ...

VICTOR_fusheng的博客 5635

原码 补码 反码

1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

m0_47505062的博客 1136
上一篇: 批处理判断并自动获取管理权限
王二小丷
博客等级 码龄7年 7粉丝 10原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值