文章目录
定点数及其分类
定点数:小数点的位置固定的二进制数。
定点数可分为:
- 无符号数:所有二进制位均为数值位,没有符号位,相当于数的绝对值,无符号数一般均指整数。
- 有符号数:首位为符号位,1表示负。定点有符号整数的小数点视作隐含在末尾,数值部分(又称为尾数)位于符号位和小数点之间;定点有符号小数的小数点视作隐含在符号位之后,其后均为数值部分。
下图为有符号数的格式。
定点有符号数的表示
定点有符号整数可以使用:原码、反码、补码、移码四种方式表示。
定点有符号小数可以使用:原码、反码、补码三种方式表示。
原码
说明:用数值部分表示真值的绝对值,符号位为1代表负。
原码整数(机器字长n+1位)的表示范围:-(2^n-1) ~ (2^n-1),其中真值0有 +0 和 -0两种方式。
原码小数(机器字长n+1位)的表示范围:-(1-2^-n) ~ (1-2^-n),其中真值0有 +0 和 -0两种方式。
反码
说明:原码的符号位不变,数值位按位取反得到反码。
补码
说明:原码的符号位不变,数值位按位取反再+1得到补码。
补码的真值0只有全0这一种表现形式,所谓的 -0 即 1,0000000表示 -2^7。
补码整数(机器字长n+1位)的表示范围:-(2^n) ~ (2^n-1)。
移码
说明:将补码的符号位取反,只能表示整数。
移码的范围与补码相同,是一一映射的关系。
移码可以很方便地判断补码数的真值的大小
说明
正数的原、反、补码均相同。
负数的原码和补码的转换互逆。
由 x 的补码求 -x 的补码:符号位、数值位全部取反,然后+1。
减法运算由加法运算代替:假设x、y均为正数,x - y = x + y补。
定点数运算
移位
移位分为 算术移位、逻辑移位、循环移位三种。
算术移位
- 原码的算术移位
右移:高位补0,低位舍弃。若舍弃0,相当于真值除以2;若舍弃1,会丢失精度。
左移:低位补0,高位舍弃。若舍弃0,相当于真值乘以2;若舍弃1,会出现严重误差。
- 反码的算术移位
右移:高位补1,低位舍弃。
左移:低位补1,高位舍弃。
- 补码的算术移位
右移(同反码):高位补1,低位舍弃。
左移(同原码):低位补0,高位舍弃。
口诀:左(移补)0右(移补)1
逻辑移位
相当于对无符号数的算术移位,即符号位也参与移动。
右移:高位补0,低位舍弃。
左移:低位补0,高位舍弃。
循环移位
被移出的位填补到另一端。
加减运算
补码加减
将减法转换为加法计算,符号位也参与运算,可能会产生上溢或下溢。
溢出判断
方法一:使用一位符号位+逻辑表达式
方法二:使用一位符号位+进位位
做异或运算,结果为1则溢出。
方法三:使用双符号位
正数符号为00,负数符号为11,若运算后,两个符号位异或为1,则有溢出。
符号扩展
短数据扩展为长数据时,多出来的位应该如何填充。
正整数的原码、反码、补码填0即可。
负整数的原码填充0,反码和补码填充1。
强制类型转换
C语言中的定点整数用补码存储,使用unsigned关键字修饰意为无符号型。
- 数据类型长度相同时:转换只改变解释方式,不改变内容。
- 长数据转短数据:高位截断,保留低位。
- 短数据转长数据:若原来的短数据是无符号数,则在高位填补0;若是有符号数,则在高位填补1。
浮点数
浮点数的意义是用有限的数据位数表示极大的数据。
格式
考虑科学计数法 2.732 * 10^8
阶码反映数值大小,对应上式的 8,与科学计数法不同的是,浮点数表示时,阶码的底(即上式的 10)通常取 2。
尾数反映精度,对应上式的2.732
例:
a的阶码为001即十进制的1,数符为1表示负,尾数数值为补码的0.1001,即原码0.0111,故真值为 2^1 * (-0.0111) = -0.111。
尾数的规格化
考虑科学计数法
第二种方式明显丢失了精度,将同样的思想迁移到浮点数尾数的规格化(左规)要求:尾数最高位必须是非0的有效值,若不是,则需进行算术左移,每左移一位则阶码减1,保证数值不变,直到满足要求。
另一种规格化(右规)发生在此种情形下:考虑科学计数法 302.6 * 10^9,小数点应在第一个非0位之后,即应变为3.026 * 10^11,浮点数的右规同理。
其他需要规格化的情形如下:
浮点数的IEEE 754标准
格式如下,以下以float为例说明
阶码(整数)用偏置值为2^(n-1) - 1的移码表示,即:将补码的符号位取反,再减一。
尾数用原码表示,因为规格化的问题,所以默认尾数部分为1.M,尾数数值部分其实表示的是M,因此虽然float型的尾数数值位为23位,但实际能表示24位数据。
阶码的取值范围为-126到+127。若阶码全1,则表示正无穷或负无穷或非数
规格化短浮点数的真值计算
以C0 A0 00 00H为例
- 转二进制1 10000001 010000…(1后面21个0)
- 数符位:为1则负。
- 尾数:尾数的真值为1.M,其中M为 010000…(1后面21个0),故真值为1.01 B
- 阶码:移码表示为10000001,即无符号数129 D,故真值为移码 - 偏置值 = 2
- 表示为二进制小数 -1.01 x 2^2,转为十进制小数为 -1.25 x 4 = -5.0
十进制小数转754标准的float
以-0.75为例
- 先转为二进制小数 -0.11。
- 确定数符为1,表示负。
- 规格化为1.M的格式,即(-1.1) x 2^-1,尾数部分为1.10000000…(1后面22个0),将M表示出来,并得到阶码真值为-1。
- 阶码的移码表示为:阶码的真值(即-1) + 偏置值127 = 126,即0111 1110。
- 表示为 1 01111110 1000000…(共22个0)