计算机中数的表示(一) - 无符号数和有符号数
文章目录
无符号数的表示
寄存器的位数反应无符号数的表示范围
有符号数的表示
机器数与真值
其中小数点的位置是以约定的方式给出的.
原码表示法
整数
正数的原码反码补码都是一样的, 负数就厉害了, 原码反码补码都不相同. 当我们用原码表示负数的时候, 只需要将这个数的符号位置为1就可以,假设这个负数为x即 $|x|+2^n$ , 因为x是负数, 所以上面的公式也就可以写为 $2^n - x$ .
小数
但是用原码表示数有一个问题, 就是会出现两个0,如下所示: $$ [+0.0000]_原 = 0.0000 \ [-0.0000]_原 = 1.0000 \ [+0]_原 = 0,0000 \ [-0]_原 = 1,0000 \ $$
很明显$[+0]_原 \not= [-0]_原$.
虽然原码表示很简单, 直观, 但是还有以下问题:
为了解决以上问题:让计算机只做加法, 找一个与负数等价的正数来代替这个负数. 补码就诞生了.
补码表示法
补的概念: 以时钟为例, 当前时钟的指针在6上, 需要将它拨到3, 可以采用两种方法: 1. 逆时针拨三格; 2. 顺时针拨九格. 即: $$ (6 - 3) \mod 12 = 3 \ (6 + 9) \mod 12 = 3 \ $$
结论: 1. 一个负数加上模之后,得到该负数的补数; 2. 一个正数和一个负数互为补数时,他们的绝对值之和为模数.
这个和时钟的例子其实是一样的.
另外正数的补数就是它本身, 两个互为补数的数加上模, 得到的结果仍然互为补数. 例如,在模等于$2^4$ 的情况下
问题来了, 如何确定$+0101$是$+0101$还是$-1011$的补数呢? 很简单用$0,0101$表示$+0101$,用$1,0101$表示$-1011$,因为补了一位符号位,所以模变成了$2^{4+1}$. 在此基础上$00101+100000=100101$,第一位丢掉, 得到的结果还是$0,0101$,且
所以补码的定义就出来了.
整数
小数
求补码的快捷方式
负数的补码就是:原码除符号位外,每位取反,末位+1. 负数的原码也可以用:补码除符号位外,每位取反,末位+1来求得.
反码表示法
为了解决原码做减法的问题, 出现了反码, 而人们发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. $[+0]_反=0,0000$, $[-0]_反=1,11111$, 然后才是出现了补码解决0的问题.
整数
负整数的补码是:原码除符号位外, 每位取反, 末位+1,即$2^{n+1}+x$ ; 而负整数的反码是:原码除符号位外, 每位取反. 所以由上式推导得出负整数的反码定义 $(2^{n+1}-1)+x$.
小数
负小数的补码是:原码除符号位外, 每位取反, 末位+1,即$2+x$, 这里的末位+1实际上是加了一个$2^{-n}$ ; 而负小数的反码是:原码除符号位外, 每位取反. 所以由上式推导得出负小数的反码定义 $(2-2^{-n})+x$.
三种机器数小结
- 原码简单,直观,但是没有解决减法问题;
- 反码解决了减法问题,但是没有解决两个0的问题;
- 补码的引入解决了上述问题.
当然也有:负数的补码除符号位外每位取反末位+1得到原码.
int8可以表示的范围是$[-128,127]$
已知$[y]_补$求$[-y]_补$
移码表示法
补码表示很难直接判断其真值大小, 如:
移码的定义
移码只有整数形式的定义, 这个与移码在计算机的数据表示中的作用有关, 移码通常表示浮点数据表示的阶码部分.
移码和补码的比较
真值, 补码和移码的对照表
移码的特点