0

0

计算机中的负数为什么用补码存储?

青灯夜游

青灯夜游

发布时间:2020-12-08 10:34:48

|

15731人浏览过

|

来源于php中文网

原创

计算机中负数使用补码存储可以简化计算机基本运算电路,使加减法都只需要用加法电路实现,用加法替代减法。补码是负数的最小正同余数,所以加一个负数和减一个正数都可以用加一个补码来表示。

计算机中的负数为什么用补码存储?

本教程操作环境:windows7系统、Dell G3电脑。

1.引子

你知道计算机中以什么形式存储整数吗?是符号位加值位吗?值位是按照正常的二进制方式存储吗?

如果后两个问题你都回答是,那就意味着当用3位二进制进行存储、且符号位0表示正1表示负时,1会存储成001,-1会存储成101。可惜事实不是这样,计算机中是用补码的形式而不是刚刚那种看上去很自然的形式存储整数,补码虽然也是用符号位加值位来表示,但表示的规则不太一样:1会存成001,-1会存成111

如果三个问题你都回答对了,你知道计算机中整数以补码的形式存储,但你知道为什么要用这种形式吗?以及「正数的补码等于原码;负数的补码等于反码加1,而反码等于原码符号位不变,其余各位取反」这样的补码到底意味着什么?(假设你不知道,请接着往下看吧 XD)

先看使用补码的目的,然后忘掉上面那个补码定义,跟我从这个目的开始,一步步探索补码的本质。
目的:为了简化计算机基本运算电路,使加减法都只需要通过加法电路实现,也就是让减去一个正数或加上一个负数这样的运算可以用加上一个正数来代替。于是改变负数存储的形式,存储成一种可以直接当成正数来相加的形式,这种形式就是补码。(正数不用变,所以接下来的讨论中一般略去正数)

2.补码是怎么把减法变成加法的?

2.1.用时钟理解减法变加法

这是一个身边的例子,当你校对时钟的时候,假设发现钟是6点,但实际上现在才2点,也就是它走快了4个小时,你可以有两种方法进行校正,一种是逆时针拨回4个小时到2点,另一种是顺时针拨6个小时到12点然后再拨2小时,也就是顺时针拨8个小时到2点。所以对于时钟的表盘来说,设-N表示逆时针拨N个小时,N表示顺时针拨动N个小时,那么-4 = +8,同样还会有 -1 = +11-5 = +7,甚至也可以 -4 = +8 = +20 = +32 = -16...

这里边隐藏了什么规律?其实在数学中,-4、+8、+20、+32、-16可以归为符合某个条件的同一类数字 —— 对于模12同余

中文维基上对于模和同余的定义是:两个整数a、b,若它们除以正整数m所得的余数相等,则称a、b对于模m同余。

而在一个可溢出计数系统中,把计数系统容量作为模,那么所有对此模同余的数在此计数系统中都会有同样的表示,而且运算等价。
比如上面例子中的时钟表盘就是一个可溢出计数系统,模为12,所以-4、+8、+20、+32、-16这些对模12同余的数在时钟表盘上的表示是一样的,而且对时针做这些操作的结果也是一样的,都会拨到同样的位置。

一个n位二进制构成的计数系统,因为会舍弃溢出的高位,所以也是一个可溢出的计数系统,它的模为\(2^n\) 。(从0数到\(2^n -1\),再多就溢出)
由此可以推理,在一个3位二进制构成的模为8的计数系统中,-2,-10,6,14可以用同样的二进制数来表示,同时减10和加14会得到一样的结果。

2.2.引出 补码

所以,只要 补码 是一个负数的正同余数,那么就能实现加这个正同余补码跟加另一个负数是一样结果的效果。对一个负数来说,有无数个正同余数满足条件,为了减少不必要的运算,可以规定补码就取其中最小的正数。

可能因为通过原码求 补码 是一个补模运算,所以它被称为 补码 。

注意,这里的 补码 都被我用特殊标识,因为这还不是计算机里真正的存储的补码形式,它应该叫补数,不过相信我,已经很接近了

3.完善 补码

3.1.这种 补码 表示还有点问题

ImgGood
ImgGood

免费在线AI照片编辑器

下载

通过转换成 补码 ,减一个数确实变成加一个数了,看似很不错,但却有一个明显的问题,那就是数本身的符号丢失了。
比如3位二进制,正常表示0~7,使用补码法它能代替-8~-1的运算,但它不能真正表示-8~-1,因为你不知道它到底是正数还是负数。
我们把负数转换成了一种在运算中更让计算机喜欢的形式,但它却丢失了自己本身作为数的信息。

怎么解决这个问题,可能有人很快就拍脑袋:那就加一位来表示正负得了。但这样的话运算时怎么办,从第二位开始算么?那进位去位的时候是不是也需要特别注意一下不要影响到符号位?你会发现这个问题并不是那么简单。

3.2.怎么完善 补码

不知道大牛是怎么想到的,问题解决得非常完美:

  • 在保持补码特性的前提下 (也就是减一个数还是照样变成加一个数)
  • 增加正负的表示 (能真正表示-8~-1了,只用看符号位是0还是1)
  • 还能让运算时不用另外区分符号位,直接把符号位当成值位进行运算,而结果的正负号自然会符合这个正负表示法(也就是符号位的进位和值位的进位都会自然地合理)

而且解决方式真的皮,简单到出人意料,就是前面你拍脑袋想到的办法:加一位来表示正负
具体做法是:在左侧高位增加一个符号位,这个符号位连同前面我们推演出的 伪补码 一同构成真正完善的补码
实现的效果:通过读取符号位能得知数的正负,同时符号位在加法运算中跟值位一样参与运算、进位、退位。

4.最后

总结一下

  • 使用补码的目的:简化计算机基本运算电路,使加减法都只需要用加法电路实现,用加法替代减法。
  • 补码为什么能达到这个目的:n位二进制可以构成一个可溢出计数系统,在这样的系统中,把计数系统容量作为模,所有对此模同余的数在此计数系统中都会有同样的表示,而且运算等价。而补码就是负数的最小正同余数,所以加一个负数和减一个正数都可以用加一个补码来表示。
  • 怎么计算补码:正数的补码是它本身;对负数求最小正同余数(模为值位的容量)放入值位,符号位置为1,得到负数的补码。

想要查阅更多相关文章,请访问PHP中文网!!

相关专题

更多
Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

44

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

58

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

11

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

65

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

36

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

75

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

21

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

35

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

R 教程
R 教程

共45课时 | 5万人学习

SQL 教程
SQL 教程

共61课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号