当前位置: 首页 > news >正文

原码、反码、补码,计算机中负数的表示

原码:将一个整数,转换成二进制,就是其原码。
如单字节的5的原码为:0000 0101;-5的原码为1000 0101。
反码:正数的反码就是其原码;负数的反码是将原码中,除符号位以外,每一位取反。
如单字节的5的反码为:0000 0101;-5的反码为1111 1010。
补码:正数的补码就是其原码;负数的反码+1就是补码。
如单字节的5的补码为:0000 0101;-5的补码为1111 1011。

在计算机中,正数是直接用原码表示的,如单字节5,在计算机中就表示为:0000 0101。

负数用补码表示,如单字节-5,在计算机中表示为1111 1011。

这儿就有一个问题,为什么在计算机中,负数用补码表示呢?为什么不直接用原码表示?如单字节-5:1000 0101。

从软件上考虑,原因有两个:

1、表示范围

拿单字节整数来说,无符号型,其表示范围是[0,255],总共表示了256个数据。有符号型,其表示范围是[-128,127]。

先看无符号,0表示为0000 0000,255表示为1111 1111,刚好满足了要求,可以表示256个数据。

再看有符号的,若是用原码表示,0表示为0000 000。因为咱们有符号,所以应该也有个负0(虽然它还是0):1000 0000。

那我们看看这样还能够满足我们的要求,表示256个数据么?

正数,没问题,127是0111 1111,1是0000 0001,当然其它的应该也没有问题。

负数呢,-1是1000 0001,那么把负号去掉,最大的数是111 1111,也就是127,所以负数中最小能表示的数据是-127。

这样似乎不太对劲,该如何去表示-128?貌似直接用原码无法表示,而我们却有两个0。

如果我们把其中的一个0指定为-128,不行么?这也是一个想法,不过有两个问题:一是它与-127的跨度过大;二是在用硬件进行运算时不方便。

所以,计算机中,负数是采用补码表示。

如 单字节-1,原码为1000 0001,反码为1111 1110,补码为1111 1111,计算机中的单字节-1就表示为1111 1111。

单字节-127,原码是1111 1111,反码1000 0000,补码是1000 0001,计算机中单字节-127表示为1000 0001。

单字节-128,原码貌似表示不出来,除了符号为,最大的数只能是127了,其在计算机中的表示为1000 0000。

2、大小的习惯

也可以从数据大小上来理解。还是以单字节数据为例。有符号数中,正数的范围是[1,127],最大的是127,不考虑符号为,其表示为111 1111;最小的是1,不考虑符号为,其表示为000 0001。

负数中,最大的是-1,我们就用111 1111表示其数值部分。后面的数据依次减1。减到000 0001的时候,我们用它标示了-127。再减去1,就变成000 0000了。还好我们有符号为,所以有两个0。把其中带符号的0拿过来,表示-128,刚好可以满足表示范围。

以上只是从软件的角度进行了分析,当然,从硬件的角度出发,负数使用补码表示也是有其原因的,毕竟计算机中,最终实现运算的还是硬件。

主要原因有三:

1、负数的补码,与其对应正数的补码之间的转换可以用同一种方法----求补运算完成,简化硬件。

如 原码 反码 补码

-127 -〉127 1000 0001 -〉 0111 1110 -〉 0111 1111

127 -〉-127 0111 1111 -〉 1000 0000 -〉 1000 0001

-128 -〉128 1000 0000 -〉 0111 1111 -〉 1000 0000

128 -〉-128 1000 0000 -〉 0111 1111 -〉 1000 0000

可以发现,负数和正数求补的方法是一样的。

2、可以将减法变为加法,省去了减法器。

在计算机中,我们可以看到,对其求补,得到的结果是其数值对应的负数。同样,负数也是如此。

运算中,减去一个数,等于加上它的相反数,这个小学就学过了。既然其补码就是其相反数,我们加上其补码不就可以了。

如:A - 127,

也就相当于:A + (-127),

又因为负数是以补码的形式保存的,也就是负数的真值是补码,既然这样,当我们要减一个数时,直接把其补码拿过来,加一下,就OK了,我们也可以放心地跟减法说拜拜了!

当然这也涉及到类型转换的问题,如单字节128,其原码是1000 0000,其补码也是1000 0000。这样我们+128,或者-128,都是拿1000 0000过来相加,这样不混乱掉了?还好,各个编程语言的编辑器对有类型转换相关的限制。

如:(假设常量都是单字节)

1 + 128, 真值的运算是 0000 0001 + 1000 0000 ,如果你将结果赋值给一个单字节有符号正数,编辑器会提示你超出了表示范围。因为运算的两个数据是无符号的,其结果也是无符号的129,而有符号单字节变量最大可以表示的是127。

1 - 128,真知的运算是 0000 0001 + 1000 0000 ,因为-128是有符号,其运算结果也是有符号,1000 0001,刚好是-127在计算机中的真值。

3、无符号及带符号的加法运算可以用同一电路完成。

有符号和无符号的加减,其实都是把它们的真值拿过来相加。真值,也就是一个数值在计算机中的二进制表示。正数的真值就是其原码,负数的真值是其补码。所以,有符号和无符号由编译器控制,计算机要做的不过是把两个真值拿过来相加。

相关文章:

  • 八大算法排序@希尔排序(C语言版本)
  • 【MySQL】数据库之主从复制和读写分离
  • Ubuntu 常用命令之 locate 命令用法介绍
  • 2022年全球运维大会(GOPS深圳站)-核心PPT资料下载
  • LeetCode 2807. 在链表中插入最大公约数
  • HLS 2017.4 导出 RTL 报错:ERROR: [IMPL 213-28] Failed to generate IP.
  • C语言—第1次作业:编译与连接基础知识
  • AI:106-基于卷积神经网络的遥感图像地物分类
  • 2023-12-25 LeetCode每日一题(不浪费原料的汉堡制作方案)
  • k8s的声明式资源管理
  • java struts2教务管理系统Myeclipse开发mysql数据库struts2结构java编程计算机网页项目
  • RocketMQ5.0延时消息时间轮算法
  • Postgresql源码(119)PL/pgSQL中ExprContext的生命周期
  • 3D视觉-相机选用的原则
  • STM32 基础知识(探索者开发板)--135讲 ADC转换
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 【391天】每日项目总结系列128(2018.03.03)
  • jquery ajax学习笔记
  • js对象的深浅拷贝
  • Mysql优化
  • PAT A1120
  • Redis 中的布隆过滤器
  • Vue.js 移动端适配之 vw 解决方案
  • 初探 Vue 生命周期和钩子函数
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 前端工程化(Gulp、Webpack)-webpack
  • 前言-如何学习区块链
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 使用Swoole加速Laravel(正式环境中)
  • 双管齐下,VMware的容器新战略
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 协程
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 如何在招聘中考核.NET架构师
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​MySQL主从复制一致性检测
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • ​如何在iOS手机上查看应用日志
  • ​用户画像从0到100的构建思路
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • (1) caustics\
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (js)循环条件满足时终止循环
  • (pojstep1.3.1)1017(构造法模拟)
  • (ZT)一个美国文科博士的YardLife
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)scrum常见工具列表
  • *** 2003