mirror of
https://github.com/Didnelpsun/CS408.git
synced 2026-10-31 12:24:51 +08:00
更新数据表达
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -508,73 +508,55 @@ $y_n$(高位)|$y_{n+1}$(低位)|操作
|
||||
|
||||
## 浮点数
|
||||
|
||||
指小数点的位置不固定,如使用科学计数法,如9.694E2。
|
||||
指小数点的位置不固定,如使用科学计数法,如$9.694E2$。
|
||||
|
||||
### 浮点数表示
|
||||
|
||||
#### 阶码与尾数
|
||||
|
||||
+ 定点数能表示的数字范围有限,但我们不能无限制地增加数据的长度。
|
||||
+ 类似科学计数法,分为阶码和尾数两个部分,阶码反映数值大小、表示范围、小数点实际位置,尾数反映精度。
|
||||
+ 类似科学计数法,分为阶符、阶码、数符和尾数四个部分,阶符和阶码反映数值大小、表示范围、小数点实际位置,数符代表浮点数的符号,尾数反映精度。
|
||||
+ 对于二进制的浮点数,阶码是常用补码或移码表示的定点整数,而尾数是常用原码或补码表示的定点小数。
|
||||
+ 若阶码的真值为$E$,尾数的真值为$M$,则浮点数的真值为$N=r^E\times M$,其中r为阶码的底,即基数,一般为2。
|
||||
|
||||
**例题** 若阶码和尾数都使用补码表示,求对应真值:a=0,01;1.1001。
|
||||
|
||||
a的阶码为0,01,是正数,所以补码与原码一样,从数值来看就是+1。而尾数1.1001代表负数,补码为反码加1,所以真值为1,0110+1=1,0111,即=-(0.25+0.125+0.0625)。所以a的真值就是2×(-0.0111)=-0.111=-0.875(相当于乘2左移一位)。
|
||||
+ 若阶码的真值为$E$,尾数的真值为$M$,则浮点数的真值为$N=r^E\times M$,其中$r$为阶码的底,即基数,一般为$2$。
|
||||
|
||||
#### 尾数规格化
|
||||
|
||||
+ 左规:出现下溢需要左规,即若尾数的高位是无效值(即为0)则会丧失精度,所以我们需要尽可能将尾数多保存一些1,从而让最高位为1。所以需要让数值左移,让小数点右移,尾数算术左移n位,阶码减n,直到尾数最高位是有效值。
|
||||
+ 右规:出现上溢需要右规,规范要求小数点要在第一个非0的数据右边,如果小数点前有超过1个有效位,则需要将数值右移,小数点左移,尾数算术右移n位,阶码加n,直到小数点在尾数最高位的右边。
|
||||
为了提高精度,充分利用尾数有效位数必须进行规格化,规定尾数必须是一个有效值。
|
||||
|
||||
**例题** a=010;00.1100,b=010;00.1000,求a+b的值。
|
||||
|
||||
已知分号前面的是阶码,后面是尾数,所以a和b都是2的010=2次幂。
|
||||
|
||||
由尾数的00代表a和b都是双符号位表示且都是正数。
|
||||
|
||||
所以a=2×2×00.1100,b=2×2×00.1000,则a+b=2×2×00.1100+2×2×00.1000=2×2×(00.1100+00.1000)=2×2×01.0100。
|
||||
|
||||
因为使用双符号位表示时,00代表正号,11表示负号,01时,称为上溢,为10时,称为下溢,此时结果为01,表示出现了上溢,这时候就需要右规。
|
||||
|
||||
阶码加一,变成2的三次方,尾数右移一位=2×2×2×00.1010。最后结果就是011;01010。
|
||||
+ 左规:出现下溢需要左规,即若尾数的高位是无效值(即为$0$)则会丧失精度,所以我们需要尽可能将尾数多保存一些$1$,从而让最高位为$1$。所以需要让数值左移,让小数点右移,尾数算术左移$n$位,阶码减$n$,直到尾数最高位是有效值。可能会进行多次。
|
||||
+ 右规:出现上溢需要右规,规范要求小数点要在第一个非$0$的数据右边,如果小数点前有超过$1$个有效位,则需要将数值右移,小数点左移,尾数算术右移$n$位,阶码加$n$,直到小数点在尾数最高位的右边。只需要一次。
|
||||
|
||||
规格化浮点数的特点:
|
||||
|
||||
1. 用原码表示的尾数进行规格化,最高位数值一定为1:
|
||||
+ 正数为0.1××...×的形式,其最大值表示为0.11...1;最小值表示为0.10...0。
|
||||
1. 用原码表示的尾数进行规格化,最高位数值一定为$1$:
|
||||
+ 正数为$0.1xx\cdots x$的形式,其最大值表示为$0.11\cdots1$;最小值表示为$0.10\cdots0$。
|
||||
+ 尾数的表示范围为$\dfrac{1}{2}\leqslant M\leqslant(1-2^{-n})$。
|
||||
+ 负数为1.1××...×的形式,其最大值表示为1.10...0;最小值表示为1.11...1。
|
||||
+ 负数为$1.1xx\cdots x$的形式,其最大值表示为$1.10\cdots0$;最小值表示为$1.11\cdots1$。
|
||||
+ 尾数的表示范围为$-(1-2^{-n})\leqslant M\leqslant\dfrac{1}{2}$。
|
||||
2. 用补码表示的尾数进行规格化,符号位与最高位数值一定相反:
|
||||
+ 正数为0.1××...×的形式,其最大值表示为0.11...1;最小值表示为0.10...0。
|
||||
+ 正数为$0.1xx\cdots x$的形式,其最大值表示为$0.11\cdots1$;最小值表示为$0.10\cdots0$。
|
||||
+ 尾数的表示范围为$\dfrac{1}{2}\leqslant M\leqslant(1-2^{-n})$。
|
||||
+ 负数为1.0××...×的形式,其最大值表示为1.01...1;最小值表示为1.00..0。(负数的补码1.0xx...x取反后就是1.1xx...x)
|
||||
+ 尾数的表示范围为$-1\leqslant M\leqslant-(\dfrac{1}{2}+2^{-n})$。(补码中强制规定1.00...0就代表-1)
|
||||
+ 负数为$1.0xx\cdots x$的形式,其最大值表示为$1.01\cdots1$;最小值表示为$1.00\cdots0$。(负数的补码$1.0xx\cdots x$取反后就是$1.1xx\cdots x$)
|
||||
+ 尾数的表示范围为$-1\leqslant M\leqslant-(\dfrac{1}{2}+2^{-n})$。(补码中强制规定$1.00\cdots0$就代表$-1$)
|
||||
|
||||
**例题** 若某浮点数的阶码、尾数用补码表示,共4+8位:0,110;1.1110100,如何规格化?
|
||||
当浮点数尾数的基数为$2$时,原码规格化数的尾数最高位一定是$1$,补码规格化数的尾数最高位一定与尾数符号位相反。基数不同,浮点数的规格化形式也不同。当基数为$4$时,原码规格化形式的尾数最高两位不全为$0$;当基数为$8$时,原码规格化形式的尾数最高$3$位不全为$0$。
|
||||
|
||||
只需要对尾数部分处理,由于负数的补码是1.0开头,而这时是1.1开头,所以必须变成1.0。
|
||||
|
||||
补码算术左移低位补0,补码算术右移,高位补1。如果是算术右移,则会一直补1,而无法变成1.0开头,所以要使用算术左移,移动三位得到1.0100000,同时阶码减3变为3,最后规格化结果为0,011;1.0100000。
|
||||
|
||||
对于浮点数,上溢和下溢有正负之分:负上溢<负数区<负下溢<0<正下溢<正数区<正上溢。
|
||||
对于浮点数,上溢和下溢有正负之分:负上溢<负数区<负下溢<$0$<正下溢<正数区<正上溢。
|
||||
|
||||
### IEEE 754标准
|
||||
|
||||
IEEE 754标准就是浮点数标准,为了解决计算机中阶码、尾数使用什么码来表示,各取多少位的问题。
|
||||
$IEEE\,754$标准就是浮点数标准,为了解决计算机中阶码、尾数使用什么码来表示,各取多少位的问题。
|
||||
|
||||
#### 移码定义
|
||||
|
||||
+ 移码的定义其实=真值+偏置值,一般取$2^{n-1}$,这时候移码才等于补码符号位取反,若移码采取其他方案则没有这个特点。
|
||||
+ 在IEEE 754标准中,规定移码的偏置值不再是128而是127,即$2^{n-1}-1$。
|
||||
+ 从而真值-128的移码为-1000 0000+0111 1111=1111 1111,-127的移码为0000 0000,0的移码为0111 1111,127的移码为1111 1110。
|
||||
+ 在$IEEE\,754$标准中,规定移码的偏置值不再是$128$而是$127$,即$2^{n-1}-1$。所以这个标准下的移码与一般的移码不同。
|
||||
+ 从而真值$-128$的移码为$-1000\,0000+0111\,1111=1111\,1111$,$-127$的移码为$0000\,0000$,$0$的移码为$0111\,1111$,$127$的移码为$1111\,1110$。
|
||||
|
||||
#### IEEE 754定义
|
||||
|
||||
+ 分为数符(表示数值正负号)、阶码(用移码表示)、尾数(用原码表示,且默认最高位为1,实际尾数位都要加1)。
|
||||
+ 标准中会将全0的-127和全1的-128做特殊的用途,所以短浮点数的真值正常范围是-126到127。
|
||||
+ 分为数符(表示数值正负号)、阶码(用移码表示)、尾数(用原码表示,且默认最高位为$1$,实际尾数位都要加$1$)。
|
||||
+ 标准中会将全$0$的$-127$(非规格化数)和全$1$的$-128$(无穷大)做特殊的用途,所以短浮点数的真值正常范围是$-126$到$127$。
|
||||
|
||||
英文类型|中文类型|数符位|阶码位|尾数位|总位数|十六进制偏置值|十进制偏置值
|
||||
:------:|:------:|:-----:|:----:|:----:|:----:|:------------:|:----------:
|
||||
@@ -585,30 +567,7 @@ long double|临时浮点数|1|15|64|80|3FFFH|16383
|
||||
+ 令数符为$S$,阶码为$E$,尾数为$M$。
|
||||
+ 规格化的短浮点数的真值为$(-1)^S\times 1.M\times2^{E-127}$。
|
||||
+ 规格化的长浮点数的真值为$(-1)^S\times 1.M\times2^{E-1023}$。
|
||||
|
||||
**例题** 将十进制数-0.75转换为IEEE 754的单精度浮点数格式表示。
|
||||
|
||||
将-0.75D首先转换为二进制为-0.11B,然后规格化变为-1.1B×0.1B。其中阶码为-1(0.1B就是代表2的负一次方)。
|
||||
|
||||
因为是负数,所以数符为1,尾数部分应该是将1.1B截断隐含的最高位1,所以应该用0.1B表示,即.100...。
|
||||
|
||||
由于阶码为-1,所以移码=阶码真值+偏置量=-1+111 1111=0111 1110。
|
||||
|
||||
所以最后就是1 0111 1110 1000 0000 0000 0000 0000 000。
|
||||
|
||||
**例题** IEEE 754的单精度浮点数C0 A0 00 00H的值是多少。
|
||||
|
||||
首先是16进制转二进制,每一个十六进制位转换为四个二进制位。所以得到1100 0000 1010 0000 0000 0000 0000 0000。
|
||||
|
||||
根据IEEE 754标准,将32位分割为数符、阶码、尾数三个部分:数符为1,阶码为100 0000 1,尾数为010 0000 0000 0000 0000 0000。
|
||||
|
||||
由于尾数最高位隐含为1,所以尾数的真值为1.010 0000 0000 0000 0000 0000。
|
||||
|
||||
由于数符为1,则这个数表示的是一个负数。
|
||||
|
||||
由于阶码由移码表示,所以看作无符号数就是129D,而单精度浮点数的偏移量为127D,所以移码真值=移码-偏置量=1000 0001-0111 1111=0000 0010=2。
|
||||
|
||||
所以浮点数的真值为-1.01B×2×2=-1.25×4=-5。
|
||||
+ 短浮点数和长浮点数都隐含一位尾数最高位$1$,而临时浮点数没有隐含位。
|
||||
|
||||
#### IEEE 754取值范围
|
||||
|
||||
@@ -618,10 +577,10 @@ long double|临时浮点数|1|15|64|80|3FFFH|16383
|
||||
双精度|$E=1$,$M=0$:$1.0×2^{1-1023}=2^{-1022}$|$E=2046$,$M=.11...1$:$1.11...1×2^{2046-1023}=2^{1023}×(2-2^{-52})$
|
||||
|
||||
+ 对于规格化短浮点数,只有$1\leqslant E\leqslant 254$时,$(-1)^S\times 1.M\times2^{E-127}$。
|
||||
+ 当阶码$E$为全0,即应该为-127D,而尾数$M$不全为0时,表示非规格化小数$\pm(0.\textrm{xx...x})_2\times2^{-126}$。(此时最高位就不默认为1了,阶码固定设置为-126)。
|
||||
+ 当阶码$E$为全0,即应该为-127D,而尾数$M$全为0时,表示真值$\pm0$,正负看数符。
|
||||
+ 当阶码$E$为全1,即应该为-128D,而尾数$M$全为0时,表示无穷大$\pm\infty$,正负看数符。
|
||||
+ 当阶码$E$为全1,即应该为-128D,而尾数$M$不全为0时,表示非数值NaN(Not a Number)。如果非法操作如0÷0等就会使用到。
|
||||
+ 当阶码$E$为全$0$,即应该为$-127D$,而尾数$M$不全为$0$时,表示非规格化小数$\pm(0.\textrm{xx...x})_2\times2^{-126}$。(此时最高位就不默认为$1$了,阶码固定设置为$-126$)。
|
||||
+ 当阶码$E$为全$0$,即应该为$-127D$,而尾数$M$全为$0$时,表示真值$\pm0$,正负看数符。
|
||||
+ 当阶码$E$为全$1$,即应该为$-128D$,而尾数$M$全为$0$时,表示无穷大$\pm\infty$,正负看数符。
|
||||
+ 当阶码$E$为全$1$,即应该为$-128D$,而尾数$M$不全为$0$时,表示非数值$NaN$($Not\,a\,Number$)。如果非法操作如$0\div0$等就会使用到。
|
||||
|
||||
### 浮点数运算
|
||||
|
||||
@@ -632,16 +591,16 @@ long double|临时浮点数|1|15|64|80|3FFFH|16383
|
||||
+ 若是阶数大的向阶数小的对齐,则阶数大的尾数值会变大,需要对尾数进行算术左移,若内存不够大很可能会引起最高有效位丢失。
|
||||
+ 若是阶数小的向阶数大的对齐,则阶数小的尾数值会变小,需要对尾数进行算术右移,若内存不够大很可能会引起最后几位丢失,即精度下降,影响较小。
|
||||
2. 尾数加减:阶数不变,对尾数进行相加减。
|
||||
3. 规格化,将数据变为整数部分为0到9的数据:
|
||||
+ 当尾数加减结果的第一位为0时需要左规,直到第一位不为0。
|
||||
+ 当结果的整数部分大于等于10需要右规,直到整数部分只有一位。
|
||||
3. 规格化,将数据变为整数部分为$0$到$9$的数据:
|
||||
+ 当尾数加减结果的第一位为$0$时需要左规,直到第一位不为$0$。
|
||||
+ 当结果的整数部分大于等于$10$需要右规,直到整数部分只有一位。
|
||||
4. 舍入:计算机中由于尾数的比特位有限,所以需要舍弃尾数的低位。舍入方法有:
|
||||
+ 直接去除。
|
||||
+ 非0进1。
|
||||
+ 非$0$进$1$。
|
||||
+ 四舍五入。
|
||||
5. 判溢出:若运算后阶码超过规定范围则溢出。尾数的溢出未必会导致整体溢出,可以通过第三四步来修补,但是阶码溢出一定会整体溢出。
|
||||
|
||||
**例题** 计算$9.85211\times10^{12}+9.96007\times10^{10}$的值并保留四舍五入六位有效尾数。
|
||||
<!-- **例题** 计算$9.85211\times10^{12}+9.96007\times10^{10}$的值并保留四舍五入六位有效尾数。
|
||||
|
||||
第一步进行对阶,变成$9.85211\times10^{12}+0.0996007\times10^{12}$。
|
||||
|
||||
@@ -651,40 +610,20 @@ long double|临时浮点数|1|15|64|80|3FFFH|16383
|
||||
|
||||
第四步因为只能保留六位有效尾数,所以保留9.95171,因为后一位是0,所以不进位为最后答案。
|
||||
|
||||
第五步因为阶码无论是10或12都是两位,所以肯定没有溢出。
|
||||
第五步因为阶码无论是10或12都是两位,所以肯定没有溢出。 -->
|
||||
|
||||
#### 浮点数加减运算
|
||||
|
||||
浮点数的加减基本上与科学计数法的加减一致。基本上浮点数的运算不可能使用IEEE 754的标准,因为位数太长不好计算。
|
||||
|
||||
**例题** 已知十进制数$X=-\dfrac{5}{256}$,$Y=+\dfrac{59}{1024}$,按机器补码浮点运算规则计算$X-Y$,结果用二进制表示,浮点数格式如下︰阶符取2位,阶码取3位,数符取2位,尾数取9位。
|
||||
|
||||
首先要将十进制的真值转换为二进制原码。因为不是IEEE 754标准,所以小数不用转换为1.xxx的格式,转成0.xxx的格式就可以了:$5D=101B$,$\dfrac{1}{256}=2^{-8}$,所以$X=-101\times2^{-8}=-0.101\times2^{-5}=-0.101\times2^{-101B}$。然后$59D=11 1011B$,$\dfrac{1}{1024}=2^{-10}$,从而$Y=+11 1011\times2^{-10}=0.111011\times2^{-4}=0.111011\times2^{-100B}$。
|
||||
|
||||
X的阶码为-101,转换为补码表示为1011,由于使用双符号位,所以变成11011;X的尾数为-0.101,补码表示为1.011,由于双符号位,所以为11.011,尾数取9位,所以拓展为11.0110 0000 0。所以X就是11011,11.011000000。
|
||||
|
||||
同理Y的阶码为-100,转换为补码表示为1100,双符号位所以变为11100;Y的尾数为0.111011,补码表示为0.111011,使用使用双符号位为00.111011,拓展为9位得到00.111011000.所以Y就是11100,00.111011000。
|
||||
|
||||
然后是阶数对齐,小阶向大阶靠拢。首先求阶差:11011-11100=11011+00100=11111=11,001=-1D。所以X的阶数比Y的阶数小一。所以对X算术右移,负数高位补1,阶码加一,从而由11011,11.011000000变为了11100,11.101100000。即变为了$-0.0101×2^{-100B}$。
|
||||
|
||||
然后是尾数加减,所以Y的尾数需要变成其负值的补码,方法是对尾数包括符号位全部取反,然后末尾加1,所以-Y=11100,11.000101000。进行相加得到10.110001000。这时候代表出现上溢出(用二进制计算尾数变成-1.001111,由于定点小数无法表示绝对值大于等于1的数,所以上溢)。
|
||||
|
||||
第三步规格化,因为使用双符号位,所以正好能补救计算结果的上溢,可以通过右规的方式规格化。所以将10.110001000算术右移,将符号位的0以及后面的数据全部右移一位,符号位补成11,得到11.011000100。然后阶码由于右移而加一,最后为11101,11.011000100。
|
||||
|
||||
第四步舍入,由于第三步右移抛弃的是0,所以没有丧失精度,就不需要舍入。
|
||||
|
||||
第五步判溢出,11101加1后等于11110,符号位都是11,所以没有溢出。
|
||||
|
||||
最后真值为11101,11.011000100。即$2^{-3}\times(-0.1001111)_2$。
|
||||
浮点数的加减基本上与科学计数法的加减一致。基本上浮点数的运算不可能使用$IEEE\,754$的标准,因为位数太长不好计算。所以加减运算一律使用补码。
|
||||
|
||||
舍入的方法:
|
||||
|
||||
+ “0”舍“1”入法:类似于十进制数运算中的“四舍五入”法,即在尾数右移时,被移去的最高数值位为0,则舍去;被移去的最高数值位为1,则在尾数的末位加1。这样做可能会使尾数又溢出,此时需再做一次右规。
|
||||
+ 恒置“1”法:尾数右移时,不论丢掉的最高数值位是“1”还是“O”,都使右移后的尾数末位恒置“1”。这种方法同样有使尾数变大和变小的两种可能。
|
||||
+ “$0$”舍“$1$”入法:类似于十进制数运算中的“四舍五入”法,即在尾数右移时,被移去的最高数值位为$0$,则舍去;被移去的最高数值位为$1$,则在尾数的末位加$1$。这样做可能会使尾数又溢出,此时需再做一次右规。
|
||||
+ 恒置“$1$”法:尾数右移时,不论丢掉的最高数值位是“$1$”还是“$0$”,都使右移后的尾数末位恒置“$1$”。这种方法同样有使尾数变大和变小的两种可能。
|
||||
|
||||
假如加减的结果为11100,10.110001011,因为尾数符号位为10代表溢出了,所以需要规格化。
|
||||
假如加减的结果为$11100,10.110001011$,因为尾数符号位为$10$代表溢出了,所以需要规格化。
|
||||
|
||||
使用0舍1入法,将尾数整体右移,并将符号位的低位移到尾数高位,阶码加移位数,符号位修改,从而变成了11101,11.011000101,溢出1,最高位为1,使用0舍1入时需要加1,从而变成11101,11.011000110。(假如尾数为全1,则加1后又会高位溢出,还需要一次右规)。恒置1法的答案是一样的。
|
||||
使用$0$舍$1$入法,将尾数整体右移,并将符号位的低位移到尾数高位,阶码加移位数,符号位修改,从而变成了$11101,11.011000101$,溢出$1$,最高位为$1$,使用$0$舍$1$入时需要加$1$,从而变成$11101,11.011000110$。(假如尾数为全$1$,则加$1$后又会高位溢出,还需要一次右规)。恒置$1$法的答案是一样的。
|
||||
|
||||
#### 浮点数强制类型转换
|
||||
|
||||
@@ -700,21 +639,21 @@ double|64|64|64
|
||||
|
||||
无损转换:
|
||||
|
||||
+ char→int→long→double。
|
||||
+ float→double。
|
||||
+ $char$→$int$→$long$→$double$。
|
||||
+ $float$→$double$。
|
||||
|
||||
由于定点数和浮点数不同,浮点数使用阶码+尾数的存储方式存储,所以定点数数值精度看位长就可以了,而浮点数数值精度看尾数长度,按IEEE 754标准有一个隐含的高位1,所以double尾数长度为53位。对于32位机器long是32位,所以转换到double的53位没有损失,而对于64位机器long是64位,double还是53位,这时候转换就会产生损失了。
|
||||
由于定点数和浮点数不同,浮点数使用阶码+尾数的存储方式存储,所以定点数数值精度看位长就可以了,而浮点数数值精度看尾数长度,按$IEEE\,754$标准有一个隐含的高位$1$,所以$double$尾数长度为$53$位。对于$32$位机器$long$是$32$位,所以转换到$double$的$53$位没有损失,而对于$64$位机器$long$是$64$位,$double$还是$53$位,这时候转换就会产生损失了。
|
||||
|
||||
int与float转换
|
||||
$int$与$float$转换
|
||||
|
||||
+ int:表示整数,范围$[-2^{31},2^{31}-1]$,有效数字32位。
|
||||
+ float:表示整数及小数,范围$\pm[2^{-126},2^{127}×(2-2^{-23})]$,有效数字23+1=24位。
|
||||
+ int→float:可能损失精度。
|
||||
+ float→>int:可能溢出及损失精度。
|
||||
+ $int$:表示整数,范围$[-2^{31},2^{31}-1]$,有效数字$32$位。
|
||||
+ $float$:表示整数及小数,范围$\pm[2^{-126},2^{127}×(2-2^{-23})]$,有效数字$23+1=24$位。
|
||||
+ $int$→$float$:可能损失精度。
|
||||
+ $float$→>$int$:可能溢出及损失精度。
|
||||
|
||||
## 算术逻辑单元
|
||||
|
||||
即运算器中的ALU。
|
||||
即运算器中的$ALU$。
|
||||
|
||||
### 原理
|
||||
|
||||
|
||||
Reference in New Issue
Block a user