目录
前言:
在上两章中讲解了五大内存函数,其中memchr函数,这个函数考察到数据内存的存储。
接下来为大家讲解整数在内存中的储存。
预备知识
认识二进制,十六进制。会二进制与十进制的相互转化运算。
由计算机的硬件决定,任何存储于计算机中的数据,其本质都是以二进制码存
储。
整数在内存中的储存
整数的二进制表示方法有三种,即原码,补码,反码。
原码
有符号的整数,三种表示方法均有符号位和数值位两部分,符号位都是“0”表示为正,用“1”表示为负,最高的一位被当作符号位,其余的是数值位。
例如:
- 正数
+5
的原码为0000 0101
。- 负数
-5
的原码为1000 0101
。- 0001+0010=0011 (1+2=3)
原码的优点是直观易懂,但存在以下问题:
- 0的表示不唯一:原码中
0
有两种表示形式,即0000 0000
(正零)和1000 0000
(负零)- 0000+1000=1000 (+0+(-0)=-0) 额,问题不大。
- 运算复杂:原码在进行加减运算时容易出错,例如两个负数相加可能得到非零结果
- 001+1001=1010 (1+(-1)= -2 )
- 噢,1+(-1)=-2,这仿佛是在逗我呢。
于是我们可以看到其实正数之间的加法通常是不会出错的,因为它就是一个很
简单的加法。
而正数与负数相加,或负数与负数相加,就要引起出乎意料的结果,这都是符号位引起的。0 分为+0 和-0 也是因他而起。
反码
原码,虽然直观易懂,但用来实现加减法的话,运算规则,总归是太复杂。于是反码来了
正整数的原码,补码,反码都相同,
反整数的三种表示方法不一样,(负数的反码就是他的原码除符号位外,按位取反。)
例如:
3 是正数,反码与原码相同,则可以表示为 0011
2. -3 的原码是 1011,符号位保持不变,低三位(011)按位取反得(100)
3. 所以-3 的反码为 1100
欧克,那么运用反码来分析以下案例吧
0001+1110=1111 (1+(-1)= - 0)
互为相反数相加等于 0,解决。虽然是得到的结果是 1111 也就是-0
1110(-1)+1101(-2)=1011(-4)
噢,又出现了新问题
(-1)+(-2)=(-4)?
但好像也没错,因为 1011(是-4 的反码,但是从原码来看,他其实是-3。我丢,反码就解决负数相加的问题啦?
nonono,再来一个例子
1110(-1)+1100(-3)=1010(-5)
- 将两个负数的反码相加:1110+1100 得到 10100
由于我们使用的是4位二进制数,所以需要丢弃最高位的进位,只保留低4位:
1010结果 1010 是一个负数的反码。为了得到其对应的十进制值,我们需要将其转换为原码:
- 将 1010 的符号位保持不变,其余位取反得到 1101。
- 1101 是 -3 的原码,因此 1010 是 -3 的反码。
但是,根据题目要求,我们需要得到 -5 的反码。根据反码的定义,-5 的反码应该是:
-5 的原码是 1010。
- -5 的反码是 1101。
然而,我们的计算结果是 1010,这与 -5 的反码不符。
这表明在反码中,两个负数相加确实会出现错误,正如证据中多次提到的那样。
证明反码确实是解决不了负数相加的问题,那么寻找本质。
两个正数相加和两个负数相加,其实都是一个加法问题,只是有无符号位罢
了。而正数+负数才是真正的减法问题
原码表示法中两个负数相加,其实在不溢出的情况下结果就只有符号位出错
而已 ( 0001+1001=1010 (1+(-1)= -2 ))
反码的负数相加出错,其实问题不大。我们只需要加实现两个负数加法时,将
两个负数反码包括符号位全部按位取反相加,然后再给他的符号位强行置
‘1’就可以了。
所以反码表示法其实已经解决了减法的问题,他不仅不会像原码那样出现两个
相反数相加不为零的情况,而且对于任意的一个正数加负数,
如:
0001(1)+1101(-2)=1110(-1) 计算结果是正确的。所以反码与原码比
较,最大的优点,就在于解决了减法的问题。
但是我们还是不满足为什么 0001+1110=1111 (1+(-1)=-0) 为什么是-0呢?
而且虽然说两个负数相加问题不大,但是问题不大,也是问题呀。
我们的计算机前辈们可忍受不了这个小问题?
所以说我们的大BOSS,补码出现了。
补码
补码:正数的补码等于他的原码
负数的补码等于反码+1。(算法的一种)
在《计算机组成原理中》,补码的另外一种算法 是
负数的补码等于他的原码自低位向高位,尾数的第一个‘1’及其右边的‘0’
保持不变,左边的各位按位取反,符号位不变。
例如:
- 正数
+5
的补码为0000 0101
(与原码相同)。- -5的反码:
1111 1010 加1得到补码。
- 负数
-5
的补码为1111 1011
例如:数字7
- 原码:
1000 0111
- 反码:
1111 1000
- 补码:
1111 1001
了解了原码,反码,补码。
那对于整形来说,存放在内存的是二进制的补码。
总结:
在本章为大家讲解整形在内存的储存。
在下一章为大家讲解大小端字节序和字节序判断。
最后感谢各位朋友的支持,咱们下一章再见!!!