浮点数的规格化表⽰⾮规格化表⽰
⽂章⽬录
1 浮点数的⼀般表⽰
阶符
阶码
数符
尾数
阶码的位数决定了浮点数的表⽰范围的⼤⼩,尾数的位数决定了浮点数的表⽰精度
阶符:阶码的符号位。1为负;0为正阶码:即幂的⼤⼩。设幂数符:尾数的符号位。1为负;0为正
尾数:尾数的⼤⼩。设尾数⼀般基数,则浮点数真值2 IEEE 754标准的浮点数
2.1 浮点数的格式
数符
阶码,⽤移码表⽰
尾数,⽤原码表⽰
类型数符阶码尾数总位数阶码偏置值(⼗进制)
指数范围(真值表⽰)指数范围(移码表⽰)
短浮点数182332127[-126,+127][+1,+254]长浮点数11152641023[-1022,+1023][+1,+2046]临时浮点数
1
15
64
80
16383
[-16382,+16383]
[+1,+32766]
从上表可以看出,IEEE 754标准的浮点数有短浮点数(单精度、float型)、长浮点数(双精度、double型)、临时浮点数三种,且数据由三部分组成:
数符:尾数的符号位。1表⽰负;0表⽰正阶码:表⽰数的幂,基为2,⽤移码表⽰
尾数:表⽰数的⼩数部分,基为2,⽤原码表⽰。且隐藏了⼀位1,这样是为了多表⽰⼀位有效位(临时浮点数⽆隐含的1)因此可知,⼀个IEEE 754标准的浮点数的值为两点说明1、关于阶码
J f
J J …J 12m
S f
S S …S 12n
e =(J J …J )12m 2M =(S S …S )12n 2
r =2N =(−1)∗J f r ∗e (−1)∗S f M
m s
E
M
浮点数的基数什么意思
N =(−1)∗m s 2∗E (1.M )2
为什么⽤移码表⽰。补码不能直观的表⽰数据的⼤⼩,⽐如⼀个8位的数据:⽤补码表⽰,8是⼤于-1的,但是补码的话 FFH > 08H,这与实际结果正好相反;⽽移码通过加上⼀个偏置值(若数据为 n 位,则通常取偏置值为,将符号位取反即可),能够反映数据之间的实际⼤⼩关系,移码表⽰,88H > 7FH,这与预期结果相符合
阶码的偏置值。阶码部分⽤移码表⽰,假设阶码为 n 位,则规定阶码偏置值取 ,因此短浮点数、长浮点数、临时浮点数阶码偏置值为。移码偏置值不是吗,这⾥为什么取 ,这是规定,记住即可
阶码的取值范围。假设阶码为 n 位,则可表⽰的范围为 ,,因此短浮点数、长浮点数的阶码取值范围为 0到255、0到2047。⼜规定当阶码全0时⽤来表⽰⾮规格化数,阶码全1时⽤来表⽰⽆穷⼤,所以阶码E的实际取值范围为 1到254、1到2046、1到32766(去掉阶码全0和全1)
阶码的实际⼤⼩。阶码采⽤移码的形式表⽰,阶码的实际⼤⼩需要减去对应的偏置值,通过这种⽅式来表⽰阶码的正负值。所以短浮点数、长浮点数的阶码实际⼤⼩为 ,即 2、关于尾数
假设尾数位数为 m 位,因为尾数部分隐含了⼀位整数1,所以尾数的实际位数为 m+1 位,因此短浮点数、长浮点数尾数实际有效位数为24、53,真值为 ,故:短浮点数的真值为
长浮点数的真值为
2.2 浮点数的取值范围
以短浮点正数为例:
当阶码和尾数都取最⼩时(E=1,M=0),表⽰的数值最⼩,阶码部分为 ,尾数部分为 隐含的1加上其余的23位0;当阶码和尾数都取最⼤时(E全1,M全1),表⽰的数值最⼤,阶码部分为 ,尾数部分为 隐含的1加上其余的23位1;
所以取值范围为 到,即
格式正数负数
单精度
双精度
2.3 类型转换时的精度损失和溢出
这⾥以C语⾔为例。C语⾔中的float、double型分别对应IEEE 754标准的单精度和双精度浮点数,⼀个int型数据占4个字节、float占4字节、double占8字节。1 溢出
当float、double向int转换时可能会发⽣溢出,⽐如有符号int型表⽰的数据范围为 ,⽽float、double类型的数据的表⽰范围超过了int类型
当double向float、int转换时可能会发⽣溢出、float向int转换时也可能会溢出
(−1)=10(11111111)=
2FFH ,(8)=10(00001000)=208H 2n −1(−1)=10(01111111)=27FH ,(8)=10(10001000)=288H 2−n −112−8−11=127、2−11−11=1023、2−15−11=163832n −12−n −110到2−n 1E −偏置值1−127=−126到254−127=127、1−1023=−1022到2046−
1023=1023
1.M (−1)∗m s (1.M )∗2E −127
(−1)∗m s (1.M )∗2E −1023
1−127=−126254−127=1271.0×2−12624个1
×2
1.11 (1127)
2到(2−−1262)×−232127−2到−−126(2−2)×−2321272到(2−−10222)×−5221023
−2到−−1022(2−2)×−5221023
2到2−−31311
2.精度损失
当int向float转换时可能会产⽣精度损失,因为int类型共四字节32位,⽽float尾数的有效位数为24位(包括隐含的1),当int型数据的有效位数超过24的话就会发⽣精度损失。⽐如
因为 m 的⼆进制表⽰为32位1,超过了float的24位,超出的1会被舍掉,所以就会产⽣精度损失。
当double向float、int转换时可能会有精度损失,因为double类型尾数的有效位数位53,超过了float的24;⽽且浮点数向整数转换时,若是⼩数部分不为0,⼀定会有精度损失,因为整数没有⼩数部分
例: 将⼗进制⼩数转换成IEEE 754标准的浮点数
例:现有⼀个⼗进制⼩数43.875,请将其转换成IEEE 754类型的短浮点数(即float类型),并将最终结果⽤⼆进制或⼗六进制表⽰。分析:
IEEE 754标准的短浮点数要符合如下⼏个标准
1. 阶码⽤移码表⽰,占8位。其值为阶码真值加偏置值127
2. 尾数⽤原码表⽰,占23位。另有⼀位隐含的整数1
3. 最⾼位为数符,占1位。0表⽰正数、1表⽰负数解答:
第⼀步 将⼗进制⼩数转换成⼆进制表⽰
⼀定要转换成 1.M 的形式,其中 M 为尾数,第⼆步 求出数符、阶码、尾数的⼆进制表⽰由题意知:数符 由第⼀步知:阶码 ,尾数因此:
1位数符为 0
8位阶码为(移码表⽰)23位尾数为(原码表⽰)第三步 整理结果
数符阶码尾数
1000 0100
010 1111 1000 0000 0000 0000
即 public  class  Main {
public  static  void  main (String [] args ) {        float  f = 43.875f ;
// 输出浮点数的 ⼆进制表⽰
System .out .println (Integer .toBinaryString (Float .floatToIntBits (f )));        // 输出浮点数的 ⼗六进制表⽰
System .out .println (Integer .toHexString (Float .floatToIntBits (f )));    }
}
unsigned
int m =FFFF FFFFH 即(2−2)×−31231
(43.875)=10(101011.111)=2(1.01011111)×25m =s 0
E =5=(101)2M =(01011111)25+127=132=(10000100)2
(010111110000000
0000
0000)2
43.875=0100
0010001011111000000000000000=422F 8000H