浮点数的表示与运算

本文探讨了浮点数的表示方法,包括定点原码、阶码和尾数的使用,重点介绍了规格化的过程及其原因,以及IEEE标准中的移码和浮点数加减运算规则。此外,文章还涉及了类型转换中的精度损失问题。
摘要由CSDN通过智能技术生成

浮点数的表示

N=(-1)^{S}\times M\times R^{E} 

S:符号

M:尾数,定点原码小数表示

R:基数,可取2的幂数,这里R=2

E:阶码

阶码的值反映浮点数小数点的实际位置

        例如:a=0,01;1.1001,其阶码和尾数均由补码表示

        a的阶码对应真值+1,a的尾数对应真值-0.0111

        a的真值=2^1 x (-0.0111)=-0.111        小数点在尾数的基础上右移一位

阶码的位数反映浮点数的表示范围

        假设阶码只有3bit,只能在尾数的基础上左移3位或右移4位,

尾数的位数反映浮点数的精度

        例如同上a=0,01;1.1001,但此时尾数从1.1001扩展为1.10010011,显然提高了a的精度


浮点数的规格化

        什么是规格化?

        规格化就是在存储空间不变的前提下尽可能提高浮点数的精度

        为什么需要规格化?

        当存储空间只有1B,尾数只有5bit,而尾数是+0.01001,由于这个0作为尾数的最高位是无效位丧失精度

        如何规格化?

        处理方法:尾数算数左移1位,阶码减1,直到最高位是有效位(左规)

·左规:当浮点数的运算结果非规格化(最高位非有效位),尾数算术左移一位阶码减一

·右规:当浮点数的运算结果溢出(双符号位出现01/10),尾数算术右移一位阶码加一(算术移位时,双符号位补码符号最左边补0/1取决于移位前最左边的符号位是0/1)

规格化浮点数的特点

 

        疑问:为什么当尾数用补码表示且尾数是负数时,最高数值位是0?        

                只是为了方便计算机判断该尾数是否进行规格化 

        以尾数为补码表示的        a=0,110;1.1110 1000为例   

        根据规格化的特点,当用补码表示尾数时,符号位与最高位相反,这里需要将尾数算数左移3bit,同时需要将阶码-3;得到规格化后的数据:0,011;1.0100 0000


IEEE标准 

前导知识:移码

移码=真值+偏置值

正常移码的偏置值是2^{n-1},例如8位移码的偏置值为1000 0000

iEEE标准的补码的偏置值为2^{n-1}-1,例如8位移码的偏置值为0111 1111,如图所示:

1. 需牢记float和double的数符,阶码,尾数的位数

2. 注意尾数部分是用原码表示最高位隐含为1,所以需要1.M开头

例1:将十进制数-0.75转换为IEEE的单精度浮点数格式

        (-0.75 )_{10}=(-0.11)_{2}=(-1.1)\times 2^{-1}

        需要对(-0.11)进行规格化处理成(-1.1)*2^(-1)

        数符:1

        阶码真值:-1,则对应移码:-1+127D=0111 1110

        IEEE表示:1 0111 1110 10000.....000        // 因为最高隐含位为1,所以此处是1而不是11

例2:IEEE754的单精度浮点数C0 A0 00 00H对应的十进制值是多少?

        C0 A0 00 00H->        1100 0000 1010 0000 0000 0000 0000 0000

         首先1可知是负数

        尾数部分,由于最高位隐含为1,所以尾数真值为(1.01)2

        阶码部分,真值=移码-偏置值=1000 0001 - 0111 1111=(2)10

        浮点数真值:(-1.01)_{2}\times 2^{2}=-1.25\times 2^{2}=-5.0

3.阶码真值的表示范围:-126~127

        即移码的1111 1111和0000 0000有另外的用途:

        当阶码E全为0,尾数M不全为0时,表示非规格化小数,即最高位为0,且阶码固定视为-126

        当阶码E全为0,尾数M全为0时,表示真值±0;

        当阶码E全为1,尾数M全为0时,表示±∞;

        当阶码E全为1,尾数M不全为0时,表示Not a Number(NaN);



浮点数的加减运算

先以10进制的加减运算为例,初步理解各步骤的含义

        1. 为什么是小阶向大阶靠齐?

        之所以这样做是因为若大阶对小阶,则尾数的数值部分的高位需移出,而小阶对大阶移出的是尾数的数值部分的低位,这样精度损失更小

        2.为什么要进行规格化处理?

        在进行尾数加减后可能造成尾数的溢出,尾数双符号位变成01 / 10的形式,此时就需要进行规格化处理

        3. 当进行规格化处理的右规时,最后一位要被移出的是1时该怎么处理?

        ·0舍1入法: 被移出的数值位为0,不做操作;被移除的数值位为1,在尾数的末尾加1,加1这一操作很有可能会再一次造成尾数溢出,又需要做一次右规

        ·恒置1法:不论右移出的数值位是多少,让右移后的尾数保证是1即可

        4. 如何进行溢出判断?

        当阶码的双符号位为01时,发生上溢产生异常,阶码的双符号位为10时,下溢出,按0处理


        

用下面例题讲解

首先将题目给出的X,Y转换成规格化后的浮点数格式

对阶时注意小阶向大阶看齐,求阶差时,将阶码部分的X-Y转换为X+(-Y);结果为-n,则X+n,并将尾数右移n位(理解:比如X的阶码-5,Y的阶码-4,那么X-Y=-1,则X应该加1,而X+1相当于尾数乘以2^1也就是左移了一位,那么为了保证数据的一致,尾数就需要右移一位)

尾数加减完,需要进行规格化:X-Y=11100,10.110001000,需要进行右规(尾数右移,阶码加1)

右移时,最后一位需要考虑舍入情况

最后根据阶符判断溢出情况


强制类型转换:

        为什么int是32转换为float32位会损失精度?

        因为float中只有1(最高位隐含为1)+23个=24有效数值,而int有31个有效数值位,转换过程损失精度

        那为什么反过来float转int可能溢出或损失精度?

        int只会取float的整数部分

       

int转换为float的详细讲解可见:C/C++ - int转float时精度损失问题_c++ int 转 float-CSDN博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值