IEEE754 学习总结

Wesley13
• 阅读 435

以下是参考《IEEE754 学习总结》并结合自己学习总结

一:前言
二:预备知识

三:浮点数的表示范围
四:将浮点格式转换成十进制数

一:前言

  前不久在分析一个程序的过程中遇到了浮点运算,也就顺便学习了一下浮点数的存放格式(IEEE754标准),此文仅作为总结,其中举了几个典型的例子,如果你想深入了解IEEE754标准,我想本文并不太适合您。

二:预备知识

-----------------------------------------------------------------------
值         存储为        指数偏移量(阶码)    尾数部分
real*4   1位符号位(s)、8位指数(e),23位尾数(m,共32位)  127(7FH)
real*8   1位符号位(s)、11位指数(e),52位尾数(m,共64位) 1023(3FFH)
real*10  1位符号位(s)、15位指数(e),64位尾数(m,共80位) 16383(3FFFH)
-----------------------------------------------------------------------

计算公式:
V=(-1)^s*2^E*M

当e(各位)为全'0'时,E=1-(2^(e(位数)-1)-1),;M=m。
如:real*4是8位,E=1-(2^(8-1)-1)=1-127=-126
即,
在real*4时:
V=(-1)^s*2^(-126)*m
在real*8时:
V=(-1)^s*2^(-1022)*m

当e(各位)不为全'0'且不为全'1'时,E=e(值)-(2^(e(位数)-1)-1);M=1+m。
即,
在real*4时:
V=(-1)^s*2^(e(值)-127)*(1+m)
在real*8时:
V=(-1)^s*2^(e(值)-1023)*(1+m)

三:浮点数的表示范围:

一个浮点数(Floating Point Number)由三个基本成分构成:符号(Sign)、阶码(Exponent)和尾数(Mantissa)。
  通常,可以用下面的格式来表示浮点数:

S

P

M

  其中S是符号位,P是阶码,M是尾数。
  根据IEEE(美国电气和电子工程师学会)754标准中的定 义,单精度(Single Precision)浮点数是32位(即4字节)的,双精度(Double Precision)浮点数是64位(即8字节)的。两者的S、P、M所占的位数以及表示方法由下表可知:

 

S

P

M

表示公式

偏移量

单精度浮点数

1(第31位)

8(30到23位)

23(22到0位)

(-1)^S*2(P-127)*1.M

127

双精度浮点数

1(第63位)

11(62到52位)

52(51到0位)

(-1)^S*2(P-1023)*1.M

1023

  其中S是符号位,只有0和1,分别表示正负。
  P是阶码,通常使用移码表示(移码和补码只有符号位相 反,其余都一样。对于正数而言,原码、反码和补码都一样;对于负数而言,补码就是其绝对值的原码全部取反,然后加1)。阶码可以为正数,也可以为负数,为 了处理负指数的情况,实际的指数值按要求需要加上一个偏差(Bias)值作为保存在指数域中的值,单精度数的偏差值为127,双精度数的偏差值为 1023。例如,单精度的实际指数值0在指数域中将保存为127,而保存在指数域中的64则表示实际的指数值-63,偏差的引入使得对于单精度数,实际可 以表达的指数值的范围就变成-127到128之间(包含两端)。
  M为尾数,其中单精度数为23位长,双精度数为52位长。IEEE标准要求浮 点数必须是规范的。这意味着尾数的小数点左侧必须为1,因此在保存尾数的时候,可以省略小数点前面这个1,从而腾出一个二进制位来保存更多的尾数。这样实 际上用23位长的尾数域表达了24位的尾数。例如对于单精度数而言,二进制的1001.101(对应于十进制的9.625)可以表达为1.001101 × 23,所以实际保存在尾数域中的值为00110100000000000000000,即去掉小数点左侧的1,并用0在右侧补齐。
  根据标准 要求,无法精确保存的值必须向最接近的可保存的值进行舍入,即不足一半则舍,一半以上(包括一半)则进。不过对于二进制浮点数而言,还多一条规矩,就是当 需要舍入的值刚好是一半时,不是简单地进,而是在前后两个等距接近的可保存的值中,取其中最后一位有效数字为零者。
  据以上分析,IEEE 754标准中定义浮点数的表示范围为:

 

二进制(Binary)

十进制(Decimal)

单精度浮点数

± (2-2^-23) × 2127

~ ± 10^38.53

双精度浮点数

± (2-2^-52) × 21023

~ ± 10^308.25

  浮点数的表示有一定的范围,超出范围时会产生溢出(Flow),一般称大于绝对值最大的数据为上溢(Overflow),小于绝对值最小的数据为下溢(Underflow)。
1、浮点数的表示约定  单精度浮点数和双精度浮点数都是用IEEE 754标准定义的,其中有一些特殊约定,例如:
  1、当P=0,M=0时,表示0。
  2、当P=255,M=0时,表示无穷大,用符号位来确定是正无穷大还是负无穷大。
  3、当P=255,M≠0时,表示NaN(Not a Number,不是一个数)。
2、非规范浮点数 当 两个绝对值极小的浮点数相减后,其差值的指数可能超出允许范围,最终只能近似为0。为了解决此类问题,IEEE标准中引入了非规范 (Denormalized)浮点数,规定当浮点数的指数为允许的最小指数值时,尾数不必是规范化(Normalized)的。有了非规范浮点数,去掉了 隐含的尾数位的制约,可以保存绝对值更小的浮点数。而且,由于不再受到隐含尾数域的制约,上述关于极小差值的问题也不存在了,因为所有可以保存的浮点数之 间的差值同样可以保存。
  根据IEEE 754标准中的定义,规范和非规范浮点数的表示范围可归纳为下表:

 

规范浮点数

非规范浮点数

十进制近似范围

单精度浮点数

± 2^-149 至 (1-2^-23)*2^-126

± 2^-126 至 (2-2^-23)*2^127

± ~10^-44.85 至 ~10^38.53

双精度浮点数

± 2^-1074 至 (1-2^-52)*2^-1022

± 2^-1022 至 (2-2^-52)*2^1023

± ~10^-323.3 至 ~10^308.3

3、与IEEE 754相关的标准  本文的结论基于IEEE 754标准,另外一个标准是IEEE 854,这个标准是关于十进制浮点数的,但没有规定具体格式,所以很少被采用。另外,从2000年开始,IEEE 754开始修订,被称为IEEE 754R,目的是融合IEEE 754和IEEE 854标准。该标准在浮点格式方面的修订有:1、加入了16位和128位的二进制浮点数格式;2、加入了十进制浮点数格式,采用了IBM公司提出的格式。

四:将浮点格式转换成十进制数

[例3.1]:
0x00280000(real*4)
转换成二进制
00000000001010000000000000000000
符号位 指数部分(8位) 尾数部分
0 00000000 01010000000000000000000
符号位=0;因指数部分=0,则:尾数部分M为m:
0.01010000000000000000000=0.3125
该浮点数的十进制为:
(-1)^0*2^(-126)*0.3125
=3.6734198463196484624023016788195e-39

[例3.2]:
0xC04E000000000000(real*8)
转换成二进制
1100000001001110000000000000000000000000000000000000000000000000
符号位 指数部分(11位) 尾数部分
1 10000000100 1110000000000000000000000000000000000000000000000000
符号位=1;指数=1028,因指数部分不为全'0'且不为全'1',则:尾数部分M为1+m:
1.1110000000000000000000000000000000000000000000000000=1.875
该浮点数的十进制为:
(-1)^1*2^(1028-1023)*1.875
=-60

四:将十进制数转换成浮点格式(real*4)

[例4.1]:
26.0
十进制26.0转换成二进制
11010.0
规格化二进制数
1.10100*2^4
计算指数
4+127=131
符号位 指数部分 尾数部分
0 10000011 10100000000000000000000
以单精度(real*4)浮点格式存储该数
0100 0001 1101 0000 0000 0000 0000 0000
0x41D0 0000

[例4.2]:
0.75
十进制0.75转换成二进制
0.11
规格化二进制数
1.1*2^-1
计算指数
-1+127=126
符号位 指数部分 尾数部分
0 01111110 10000000000000000000000
以单精度(real*4)浮点格式存储该数
0011 1111 0100 0000 0000 0000 0000 0000
0x3F40 0000

[例4.3]:
-2.5
十进制-2.5转换成二进制
-10.1
规格化二进制数
-1.01*2^1
计算指数
1+127=128
符号位 指数部分 尾数部分
1 10000000 01000000000000000000000
以单精度(real*4)浮点格式存储该数
1100 0000 0010 0000 0000 0000 0000 0000
0xC020 0000

拓展阅读:http://blog.csdn.net/fireseed/article/details/2180

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
PPDB:今晚老齐直播
【今晚老齐直播】今晚(本周三晚)20:0021:00小白开始“用”飞桨(https://www.oschina.net/action/visit/ad?id1185)由PPDE(飞桨(https://www.oschina.net/action/visit/ad?id1185)开发者专家计划)成员老齐,为深度学习小白指点迷津。
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这