一文带你秒懂IEEE 754浮点数

描述

一、简介

 

1、常见的浮点数表示方式是IEEE 754标准,它规定了浮点数的存储格式和运算规则,这个标准定义了两种浮点数表示:单精度和双精度。

2、任何一个浮点数的二进制数可以写为:NUM = (-1) ^ S* 2 ^ E * M 。以float32类型举例:

    2.1、S表示符号:S为0时表示一个正数;当S为1时表示一个负数

    2.2、E表示阶乘、指数:E是一个无符号整数,所以E的取值范围为(0~ 255)。但是在计数中指数是可以为负的,所以规定在存入E时,在它原本的值上加上中间数(127),在使用时减去中间数(127),这样E的真正取值范围就成了(-127~128)。对于E还分为以下三种情况:

(1)E不全为0,不全为1:这时就用正常的计算规则,E的真实值就是E的字面值减去127(中间值),M的值要加上最前面的省去的1

(2)E全为0:这时指数E等于1-127为真实值,M不再加上舍去的1,而是还原为0.xxxxxxxx小数。这样为了表示0,和一些很小的整数。

(3)E全为1时分三种浮点数特殊情况:M全为0时,±无穷大(取决于符号位);M为非全0时,表示NaN。

编程

    2.3、M表示有效数字、尾数:规定M的值一定是1 <= M < 2,可以写成1.xxxxxxx的形式,所以规定M在存储时舍去第一个1,只存储小数点之后的数字。这样做节省了空间,以float类型为例,就可以保存23位小数信息,加上舍去的1就可以用23位来表示24个有效的信息

3、单精度(32位):符号位(1 bit)、指数位(8 bits)、尾数位(23 bits)

4、双精度(64位):符号位(1 bit)、指数位(11 bits)、尾数位(52 bits)

5、存储格式:以float32的浮点数举例如下图

编程

二、十转二进制

 

1、以float32浮点数和23.375浮点数举例

2、整数转换方式:对2取余

 

编程

3、小数转换方式:对小数进行2乘留整再对小数2乘直至为小数部分为0

编程

4、合并整数和小数部分:10111 和小数部分 0.011 得到二进制浮点数 10111.011

5、规范化和指数表示6、最终,将符号位、指数和尾数合并,得到IEEE 754标准的二进制浮点数表示为:

编程

三、二转十进制

1、以上面的23.375浮点数的转换结果0 10000011 01110110000000000000000举例
2、主要是这个公式:NUM = (-1) ^ S * 2 ^ E * M,分三步第一步:(-1) ^ S第二步:2 ^ E第三步:M3、符号位 (-1) ^ S:(-1)^04、指数位 2 ^ E :将二进制转十进制为131,然后减去偏移值127,得到5、那么这里就是 2 ^ 46、M:分两步

  1. 先转换为二进制浮点数,根据E不全为0或1的规则得到:1.01110110000000000000000
  2. 再用2的阶乘的方式转换为浮点数,如下:

编程

四、误差

1、如下代码展示

编程

2、原因:在计算机中,由于浮点数的表示方式是有限的,有些十进制小数无法精确表示为二进制浮点数。这导致在进行浮点数运算时可能出现舍入误差,进而导致预期的结果和实际的二进制浮点数表示的结果不完全相等。

3、将0.1转为二进制

编程

4、这个过程会一直持续下去,因为 0.1 在二进制中是一个无限循环小数。

5、将-0.1转为二进制

6、首先,-0.1 可以表示为二进制的补码形式。如果我们考虑一个32位的单精度浮点数,其符号位为1,指数位为127(偏移值),尾数部分为 0.00011001100110011001100...(重复的 1100 模式)。

7、进行加法操作

编程

8、这个结果实际上是一个无限循环的二进制小数。由于计算机内存是有限的,最终只能存储一个有限位数的二进制小数,因此可能会进行截断或舍入操作,导致精度损失。

9、在实际计算机系统中,这种舍入误差可能会导致结果不等于精确的零,因为我们不能精确地表示无限循环小数。这就是为什么在计算机编程中进行浮点数比较时,通常使用一个小的误差范围而不是直接比较相等。

10、改进方式

编程

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分