IEEE-754双精度浮点数

IEEE二进制浮点数算术标准(IEEE 754)规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现),本文介绍64位双精度浮点数。

存储结构

IEEE-754双精度浮点数(double floating-point)存储为64bit,由符号位(s)、有偏指数(e)、小数部分(f)组成:

组成 描述 位数 位置
sign 符号,0表示正,1表示负 1bit 63
exponent 指数部分 11bit 52-62
fraction 小数部分 52bit 0-51

类型划分

11位的指数部分可存储00000000000 ~ 11111111111(十进制范围为0 ~ 2047),取值可分为3种情况:

  1. 11位指数不为00000000000和11111111111,即在00000000001 ~ 11111111110(1 ~ 2046)范围,这被称为规格化。
  2. 指数值为00000000000(0),这被称为非规格化
  3. 指数值为11111111111(2047),这是特殊值,有两种情况:
    • 当52位小数部分f全为0时,若符号位是0,则表示+Infinity(正无穷),若符号位是1,则表示-Infinity(负无穷)
    • 当52位小数部分f不全为0时,表示NaN(Not a Number)

规格化

规格化下,浮点数的形式可表示为:
(−1)s×1.bbb⋯b⏟f(有效52位)(ccc⋯⏟53位及以后)×2e−1023(0<e<2047)(-1)^s\times1.\underbrace{bbb\cdots b}_{f(有效52位)}(\underbrace{ccc\cdots}_{53位及以后})\times2^{e-1023} \quad (0< e < 2047)(−1)s×1.f(有效52位)bbb⋯b​​(53位及以后ccc⋯​​)×2e−1023(0<e<2047)
其中:

  • s为0或1,0表示正数,1表示负数,对应1bit的符号位
  • f为52位有效位,其中的每一位b是0或1,对应52bit的小数部分(不足52位补0)
  • c是超出52位的部分(如果有的话,需要舍入(精度会丢失),规则下述)
  • e为十进制数值,其11位的二进制数值对应11bit的指数部分
  • 1023移码,移码值为 2n−1−12^{n-1}-12n−1−1,这里的n表示指数位数,对于64bit的双精度存储,n是11

十进制中,12345可表示为1.2345×1041.2345\times10^41.2345×104;二进制中,10011可表示为1.0011×241.0011\times2^41.0011×24

先看个简单例子,计算2.25的双精度浮点数:

2.25转为二进制为10.01,10.01转为上述表示法为 1.001⏟f×211.\underbrace{001}_{\scriptsize{f}}\times2^11.f001​​×21,可得:

  • 数值为正,因此符号位是0
  • 小数为001,不足52位,补0,得到
    0010000000000000000000000000000000000000000000000000⏟001后49个0共52位\underbrace{0010000000000000000000000000000000000000000000000000}_{001后49个0\quad共52位}001后49个0共52位0010000000000000000000000000000000000000000000000000​​
  • 指数e-1023 = 1,则 e = 1024,二进制值为10000000000⏟11位\underbrace{10000000000}_{11位}11位10000000000​​

综上,将1位符号、11位指数、52位小数整合可得到2.25的双精度浮点数表示:
0⏟s10000000000⏟e0010000000000000000000000000000000000000000000000000⏟f\underbrace{0}_{s}\underbrace{10000000000}_{e}\underbrace{0010000000000000000000000000000000000000000000000000}_{f}s0​​e10000000000​​f0010000000000000000000000000000000000000000000000000​​
上述步骤反向操作可得到十进制值

上面这个例子中,小数部分不存在舍入的问题(位数小于52位),那么如果小数超出了52位,如何处理呢?有以下几种情况:

1、第53位是0,无需处理
2、第53位是1且53位之后全是0:

  • 若第52位是0,无需处理;
  • 若第52位是1,那么向上舍入

3、第53位是1,且之后不全是0:那么向上舍入

再看一个例子,计算23.3的双精度浮点数:
23.3转为二进制为
10111.0100110011001100110011001100110011001100110011001100⋯⏟1100循环10111.0100110011001100110011001100110011001100110011001100\underbrace{\cdots}_{1100循环}10111.01001100110011001100110011001100110011001100110011001100循环⋯​​
改写为
1.0111010011001100110011001100110011001100110011001100⏟52位1100⋯⏟1100循环×241.\underbrace{0111010011001100110011001100110011001100110011001100}_{52位}\underbrace{1100 \cdots}_{1100循环}\times2^41.52位0111010011001100110011001100110011001100110011001100​​1100循环1100⋯​​×24
数值为正,因此符号位是0;指数e -1023 = 4,e = 1027 = 10000000011,因此指数部分是10000000011;小数位无限循环,53位是1且之后不全是0,符合上述规则3,因此向上舍入,第52位由0变为1,最终小数部分为:
011101001100110011001100110011001100110011001100110101110100110011001100110011001100110011001100110011010111010011001100110011001100110011001100110011001101
整合后得到23.3的双精度浮点数表示:
0⏟s10000000011⏟e0111010011001100110011001100110011001100110011001101⏟f\underbrace{0}_{s}\underbrace{10000000011}_{e}\underbrace{0111010011001100110011001100110011001100110011001101}_{f}s0​​e10000000011​​f0111010011001100110011001100110011001100110011001101​​


非规格化

非规格化可用以下形式表示(小数点前面是0):
(−1)s×0.bbb⋯b⏟f(52位)×2e−1022(e=0)(-1)^s\times0.\underbrace{bbb\cdots b}_{f(52位)}\times2^{e-1022} \quad (e=0)(−1)s×0.f(52位)bbb⋯b​​×2e−1022(e=0)
当f=0f=0f=0(52位小数全为0)时,表示的值是0:s=0s=0s=0表示-0,s=1s=1s=1表示+0


特殊值

当e=2047e=2047e=2047(11位指数全为1)时:

  • 若f>0f>0f>0,表示NaN
  • 若f=0,s=0f=0,s=0f=0,s=0,表示+Infinity
  • 若f=0,s=1f=0,s=1f=0,s=1,表示-Infinity

数值范围

1、在规格化中,当指数e最大(前10位为1,11位为0,即2046)且小数f最大(52位全为1)时,能表示出最大正值,为
1.111⋯11⏟52个1×22046−1023=111⋯11⏟53个1000⋯00⏟971个01.\underbrace{111\cdots11}_{52个1}\times2^{2046 - 1023} = \underbrace{111\cdots11}_{53个1}\underbrace{000\cdots00}_{971个0}1.52个1111⋯11​​×22046−1023=53个1111⋯11​​971个0000⋯00​​
转为十进制值为1.7976931348623157e+308,则能表示的最小负值-1.7976931348623157e+308

2、在规格化中,当指数e最小(前10位为0,11位为1,即1)且小数f最小(52位全为0)时,能表示出最小正值,为
1.000⋯00⏟52个0×21−1023=0.000⋯00⏟1021个011.\underbrace{000\cdots00}_{52个0}\times2^{1 - 1023} = 0.\underbrace{000\cdots00}_{1021个0}11.52个0000⋯00​​×21−1023=0.1021个0000⋯00​​1
转为十进制值为2.2250738585072014e-308,则能表示的最大负值-2.2250738585072014e-308


在非规格化中,指数e为0
1、当小数f最大(52位全为1)时,能表示出最大正值,为
0.111⋯11⏟52个1×2−1022=0.000⋯00⏟1022个0111⋯11⏟52个10.\underbrace{111\cdots11}_{52个1}\times2^{-1022} = 0.\underbrace{000\cdots00}_{1022个0}\underbrace{111\cdots11}_{52个1}0.52个1111⋯11​​×2−1022=0.1022个0000⋯00​​52个1111⋯11​​
转为十进制值为2.225073858507201e-308,则最小负值-2.225073858507201e-308

2、当小数f最小(前51位为0,52位为1)时,能表示出最小正值,为
0.000⋯01⏟第52位为1×2−1022=0.000⋯00⏟1073个010.\underbrace{000\cdots01}_{第52位为1}\times2^{-1022} = 0.\underbrace{000\cdots00}_{1073个0}10.第52位为1000⋯01​​×2−1022=0.1073个0000⋯00​​1
转为十进制值为5e-324,则最大负值-5e-324

整数范围(精确整数,无精度丢失)

当 e - 1023 = 52,即e = 1075,小数f最大(52位全为1)时,能表示出最大安全正整数,为
1.111⋯11⏟52个1×252=111⋯11⏟53个11.\underbrace{111\cdots11}_{52个1}\times2^{52} = \underbrace{111\cdots11}_{53个1}1.52个1111⋯11​​×252=53个1111⋯11​​
转为十进制值为253−12^{53}-1253−1 = 9007199254740991,则能表示的最小安全负整数-9007199254740991

总结

1、javascript中的数值统一采用IEEE-754双精度存储,因此在计算时可能出现精度丢失,导致奇怪的结果,如 0.1 + 0.2 !== 0.3

2、下表列出了IEEE-754中的数值边界值,其中某些值对应javascript中的数值常量

- 最小负值 最大负值 最小正值 最大正值 最小安全负整数 最大安全正整数
规格化 -1.7976931348623157e+308 -2.2250738585072014e-308 2.2250738585072014e-308 1.7976931348623157e+308(Number.MAX_VALUE) -9007199254740991(Number.MIN_SAFE_INTEGER) 9007199254740991(Number.MAX_SAFE_INTEGER)
非规格化 -2.225073858507201e-308 -5e-324 5e-324(Number.MIN_VALUE) 2.225073858507201e-308 x x

IEEE 754可以表示的数值范围是:
[−1.7976931348623157×10308,−5×10−324]∪[5×10−324,1.7976931348623157×10308][-1.7976931348623157\times10^{308},-5\times10^{-324}] \cup [5\times10^{-324},1.7976931348623157\times10^{308}][−1.7976931348623157×10308,−5×10−324]∪[5×10−324,1.7976931348623157×10308]
超过1.7976931348623157e+308Infinity,小于-1.7976931348623157e+308-Infinity,在(-5e-324,5e-324)之间的数显示为0

IEEE-754 64位双精度浮点数存储详解相关推荐

  1. C#关于64位双精度浮点数Double(DReal)一步步按位Bit进行解析

    有一篇我们是获取float如何转化为字节的过程,这次我们测试double是如何转化为64位二进制的. C#关于32位浮点数Float(Real)一步步按位Bit进行解析 基本说明 浮点数的32位N=1 ...

  2. 64位java_一文详解 Java 的八大基本类型!

    自从Java发布以来,基本数据类型就是Java语言中重要的一部分,本文就来详细介绍下每种基本类型的具体使用方法和限制. 以下为译文: 几年前,我开始编写了一系列有关Java入门的文章,我觉得有必要将其 ...

  3. 【数据的存储】浮点数在内存中的存储详解【超详细的保姆级别教程,让面试官心服口服】手撕浮点数存储使用方式

    [数据的存储]浮点数在内存中的存储详解[超详细的保姆级别教程,让面试官对你心服口服]手撕浮点数存储使用方式 作者: @小小Programmer 这是我的主页:@小小Programmer 在食用这篇博客 ...

  4. 64位 iee754_深入理解IEEE754的64位双精度

    前言 最近在JavaScript使用整数时,遇到因为数字超出最大值的问题.回忆起Cifer中学时代玩魔兽世界,金币最大为21万4748金币36银币47铜币,即2147483647,当时并不懂原因,还以 ...

  5. 单精度浮点数和双精度浮点数存储

    IEEE 754中 单精度浮点数和双精度浮点数存储 IEEE 754中 单精度浮点数和双精度浮点数存储 我们先了解一下 单精度浮点数 和 双精度浮点数 的基本信息. 名称 占用内存(bit;位) 内存 ...

  6. 单精度浮点数存储、双精度浮点数存储

    单精度浮点数存储 其中最高位为符号位S:0代表 +,1代表-,E为指数位,M有有效位 例如: 那如果此时我的指数是一个负数呢? 这里IEEE还有特别规定: 有效数字M: M可以写成1.×××,其中×× ...

  7. MongoDB中关于64位整型存储解决方案

    为什么80%的码农都做不了架构师?>>>    社区内一哥们@smcboy 提出关于php中操作MongoDB存储整数问题,找到点资料花点时间翻译过来,是个很好的学习方式.@红薯 那 ...

  8. pcmark2 android测试,PCMark安卓版升级:支持64位ARM架构 存储测试为Storage 2.0

    作为一款跨平台的评测软件,PCMark的Android版本最近升级到了v3.0.4054.这个版本变化很大,官方支持64位ARM架构,跑分不能向下比较. ARM处理器长期支持64位,但支持的APP应用 ...

  9. IEEE754浮点数格式详解

    IEEE754浮点数格式详解 几乎所有计算机都支持二进制数据表示,即能直接识别二进制数据表示并具有相应的指令系统.通常采用的二进制定点数据表示主要有:符号数值.反码.补码以及带偏移增值码四种形式,其中 ...

最新文章

  1. 干货丨机器学习知识点(人工智能篇)
  2. mysql事务在提交后才发送给数据库执行_从一个线上问题分析binlog与内部XA事务提交过程...
  3. JAVA_OA(六):SpringMVC拦截器
  4. Android开发面试题之求一个数的N次幂手写算法
  5. AngularStrap -- Popovers
  6. Centos 6.5部署nginx+uwsgi+django
  7. 父亲节,程序员几条代码硬核示爱
  8. unity 打包减小包体大小
  9. QQ免费企业邮箱申请配置
  10. 海底捞激励员工的方法符合哪些激励理论的建议
  11. 用python批量爬qq号_简单教程 8位QQ靓号爬取并过滤 – Python版
  12. H: Yet Another Crosses Problem
  13. 常识-键盘锁定英文输入法,即使按shift也无法切换回中文
  14. 阿里云服务器Ubuntu系统搭建mqtt服务器
  15. android 仿微信账单生成器手机版式,2020微信年度账单生成器
  16. matlab如何实现动态显示,matlab 坐标图动画,动态显示数据
  17. 辽宁2010省赛NEW RDSP MODE I (思维,推导公式)
  18. 数据结构考纲笔记概览
  19. ACRush 楼天成回忆录
  20. 2020年 网络 “十大热词” 出炉,你熟悉哪些?

热门文章

  1. Jetson TX1板载相机调用测试
  2. 用java编写spark程序,简单示例及运行
  3. 用Stm32CubeMX在STM32F107上移植LWIP(PHY:DM9161A)
  4. 经典坦克大战再现(三)
  5. 【NOIP 2017 提高组 DAY1 T1】小凯的疑惑
  6. 主机游戏销售数据分析练习
  7. python bootstrap安装_Django配置Bootstrap, js实现过程详解
  8. 定制电竞比分网LOL英雄联盟数据API接口调用代码
  9. Consider defining a bean of type问题解决
  10. 如何提高电商仓储管理效率?