一张图看懂原码、反码、补码、移码
2014-05-04 21:37
441 查看
前言
原码、反码、补码其实两年前就讲过,只是当时的理解太过肤浅或者直接说就是没有理解,因为对于数学比较发怵的我看到那么多的公式很是脑袋大,所以想要硬记也记不住。这次讲课的时候好歹知道了运算规则,但别人一问为什么,立马那个冏啊~好了,废话不多说了,开始进入正题(如果我的理解有偏差,恳请各位大虾不吝指出):一张图胜过千言万语,下面的这张是本篇想要说的大概内容
原码
我们知道,计算机是以0和1进行运算的,而且内部只有加法运算器,但日常生活中使用的却是十进制,并且有正负之分。于是我们发明了原码:最高位存放符号(正数用0表示,负数用1表示),其余为真值位。这样就可以方便的进行算术运算了。但很快,我们发现在进行加、乘、除的时候结果均正确,减法却出现了一些问题,下面举个例子:假设计算机的字长为8 byte,那么
(2)D -(2)D = (2)D +(-2)D = (0)D D表示十进制
(00000010)原+(10000010)原=(10000100)原=(-4)D
反码
以上结果用原码进行计算的显然不正确。因为正数计算的时候没有问题,那么肯定出现在负数身上,为了解决这个问题,我们引入了反码:对负数的原码符号位不变,真值位进行逐位取反。反码的运算如下:(1)D-(2)D=(-1)D
(00000001)反+(11111101)反=(11111110)反=(10000001)原=(-1)D
而对于在原码中提到的十进制2-2=0的算法如下:
(00000010)反+(11111101)反=(11111111)反=(10000000)原=(-0)D
补码
发现得到的结果是-0!而在我们的日常计算中,0是不分正负的。为了解决这个问题,我们引入了补码:对负数的补码真值位加1。如果最高位(符号位)有进位,则进位被舍弃。在补码中用(-128)D代替了(-0),故补码的表示范围为(-128~0~127)共256个。需要注意的是:(-128)D没有对应的原码和反码。补码的十进制2-2=0的运算如下:
(00000010)补+(11111110)补=(00000000)补=(00000000)原=(0)D
可以发现补码的运算无误(大家感兴趣的话可以使用其他式子练习),因此,在计算机系统中,数值一律使用补码进行存储,它能将符号位和真值位统一进行处理。
移码
但是我们不能高兴的太早,还有一个问题:大家有没有发现(-2)D的原码、反码、补码分别大于(2)D的原码、反码、补码?这跟我们日常的认知不相符,为了解决这个问题,我们引入了移码的概念(其实这个并不是移码的来历,只是为了好记一些而已):如果机器字长为n,规定数X上增加一个偏移量2n-1。那么,这个时候[-2]移=27+(-2)D =(1000000)补+(11111110)补=(01111110)补
[2]移=27+(2)D =(10000000)补+(00000010)补=(10000010)补
[-2]移<[2]移
结语
终于把我要说的说完了,虽然费了不少的劲去整明白来龙去脉,但明白了原理之后再进行计算就相当容易了。以后的学习中也应该去养成这个习惯,知其然知其所以然,多问几个为什么,当不知道答案的时候说明肯定对这部分的知识还没有掌握到位。接下来,努力吧,少年!相关文章推荐
- Oracle数据库乱码(字符集)问题解决方案
- net run time error
- 无奈卸载Clover 转投TotalCommand
- codeforces --- Round #244 (Div. 2) B. Prison Transfer
- 动态规划(2)-完全背包【模板】
- jax-ws使用笔记
- leetcode第一刷_Linked List Cycle II
- 关于打印机 —— DEVCAPS2 程序代码分析
- 街道问题_DP
- 面试题 自己实现strcpy 函数
- HDU 2802 F(N) (找循环节)
- 复习java基础第二天(异常处理)
- 浪度九州城首页到内容页
- 解决cobbler reposync 同步 epel 和updates源报错
- windows编程->线程函数
- 七种角度分析对应分析方法
- 什么是Hash算法
- 2014华为创新杯OJ试题
- (详细)Hibernate查询技术(Query、Session、Criteria),Hibernate的三种状态,Hibernate集合struts2实现登录功能(二)
- HashMap--面试必问的集合类