IEEE-754 64位双精度浮点数存储详解

2023-11-12

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. b b b ⋯ b ⏟ f ( 有 效 52 位 ) ( c c c ⋯ ⏟ 53 位 及 以 后 ) × 2 e − 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) bbbb(53 ccc)×2e1023(0<e<2047)
其中:

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

十进制中,12345可表示为 1.2345 × 1 0 4 1.2345\times10^4 1.2345×104;二进制中,10011可表示为 1.0011 × 2 4 1.0011\times2^4 1.0011×24

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

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

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

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

上面这个例子中,小数部分不存在舍入的问题(位数小于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 循 环 × 2 4 1.\underbrace{0111010011001100110011001100110011001100110011001100}_{52位}\underbrace{1100 \cdots}_{1100循环}\times2^4 1.52 01110100110011001100110011001100110011001100110011001100 1100×24
数值为正,因此符号位是0;指数e -1023 = 4,e = 1027 = 10000000011,因此指数部分是10000000011;小数位无限循环,53位是1且之后不全是0,符合上述规则3,因此向上舍入,第52位由0变为1,最终小数部分为:
0111010011001100110011001100110011001100110011001101 0111010011001100110011001100110011001100110011001101 0111010011001100110011001100110011001100110011001101
整合后得到23.3的双精度浮点数表示:
0 ⏟ s 10000000011 ⏟ e 0111010011001100110011001100110011001100110011001101 ⏟ f \underbrace{0}_{s}\underbrace{10000000011}_{e}\underbrace{0111010011001100110011001100110011001100110011001101}_{f} s 0e 10000000011f 0111010011001100110011001100110011001100110011001101


非规格化

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


特殊值

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

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

数值范围

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

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


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

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

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

当 e - 1023 = 52,即e = 1075,小数f最大(52位全为1)时,能表示出最大安全正整数,为
1. 111 ⋯ 11 ⏟ 52 个 1 × 2 52 = 111 ⋯ 11 ⏟ 53 个 1 1.\underbrace{111\cdots11}_{52个1}\times2^{52} = \underbrace{111\cdots11}_{53个1} 1.521 11111×252=531 11111
转为十进制值为 2 53 − 1 2^{53}-1 2531 = 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 × 1 0 308 , − 5 × 1 0 − 324 ] ∪ [ 5 × 1 0 − 324 , 1.7976931348623157 × 1 0 308 ] [-1.7976931348623157\times10^{308},-5\times10^{-324}] \cup [5\times10^{-324},1.7976931348623157\times10^{308}] [1.7976931348623157×10308,5×10324][5×10324,1.7976931348623157×10308]
超过1.7976931348623157e+308Infinity,小于-1.7976931348623157e+308-Infinity,在(-5e-324,5e-324)之间的数显示为0

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IEEE-754 64位双精度浮点数存储详解 的相关文章

随机推荐

  • docker安装nginx并映射文件

    docker下载nginx docker pull nginx 启动nginx docker run name nginx p 80 80 d nginx 3 映射配置文件 mkdir p mydata nginx mkdir p myda
  • 使用Arduino Uno开发板和LCD显示屏自制pH计

    pH计用来测量液体的酸碱度 它的读数范围为1 14 其中1表示最酸性的液体 而14表示最碱性的液体 pH值为7表示既不是酸性也不是碱性的中性物质 现今 pH计在我们的生活中起着非常重要的作用 并且被用于各种应用中 例如 它可以在游泳池中使用
  • 1988-2020年各省、分城乡基尼系数、基尼系数计算及相关经典文献、1978-2019年中国省市恩格尔系数表、泰尔指数计算模板、208个地级市和31个省、市城乡泰尔指数

    一 各省 分城乡基尼系数 1 数据来源 中国统计年鉴 2 时间跨度 1988 2020 3 区域范围 全国所有省份 4 指标说明 参照田为民的文章 中国基尼系数计算及其变动趋势分析 里基尼系数的计算方法 部分数据如下 二 基尼系数计算及相关
  • 经典卷积神经网络--AlexNet分析与pytorch代码

    2012年AlexNet卷积神经网络结构被提出 并且以高出第二名10 的准确率获得2012届ImageNet图像识别大赛中获得冠军 使得CNN成为了图像分类核心算法模型 AlexNet网络特点 1 AlexNet一共有八层 五个卷积层和三个
  • 为什么大多数场景要用拦截器而不是过滤器

    过滤器是javaWeb提供的一个技术 拦截器是基于框架的 拦截器太强大了 什么请求都会被拦截 跨域请求也会 跨域请求是不携带请求参数的 如果对跨域请求进行签名校验则会失败 所以要先判断是否是跨域请求 在进行参数判断 而对签名的校验是业务参数
  • 树莓派 QT项目开机自启动

    我自己用qt设置了一个界面 如何让他开机自启动呢 目录 1 生成qt项目的可执行文件 2 编写一个自启动脚本 3 重启树莓派 1 生成qt项目的可执行文件 QT项目的可执行文件就是 exe文件 首先在qt中打开 点击红色方框图标 选择Rel
  • python 学习笔记(一)元组

    元组运算符 与字符串一样 元组之间可以使用 号和 号进行运算 这就意味着他们可以组合和复制 运算后会生成一个新的元组 Python 表达式 结果 描述 len 1 2 3 3 计算元素个数 1 2 3 4 5 6 1 2 3 4 5 6 连
  • 用python将数据保存至现存excel的指定sheet内

    import openpyxl import pandas as pd def save to excel sheet data path excel sheet name 将DataFrame数据存入指定excel的指定表格名称 wb o
  • uint 数据类型理解

    uint unsigned int 无定义整型 uint不能为负数 int可以为负数 uint和int的区别 uint无符号int 什么是有符号 难道负数就是有符号 一 指代不同 1 uint 对应于无符号整数 2 int 一种数据类型 在
  • 【MATLAB函数】function定义函数

    1 函数声明 定义 function 返回变量列表 函数名 输入变量列表 如 function y1 yN myfun x1 xM end 声明一个名为myfun 的函数 该函数接受输入参数 x1 xM 并返回输出参数 y1 yN 此声明语
  • from shapely.geos import lgeos 出错

    Shapely 安装以后出现下面这个错误 from shapely coords import CoordinateSequence File C ProgramData Anaconda3 envs db lib site package
  • 爬虫入门使用

    用第三方服务 https www bazhuayu com https www jisouke com pro product html 用他们做出来的文件在放到数据库中 参考资料 jsoup
  • pysot 运行demo注意事项

    研究siam rpn 首先跑通demo 按照install md安装环境 path to conda pysot都是到conda pysot的路径 linux中 export PYTHONPATH path to pysot PYTHONP
  • C++开发者的机会在哪里?盘点C/C++就业方向

    引用一个校招脉友的提问 现在C 的机会是不是越来越少了 这个问题还是老生常谈 看看大家怎么说 不难发现 c 很多的岗位很多都存在两个共性 第一个 岗位比较高端 任职要求高 第二个 部分在传统行业 流动性不大但薪资较其他的语言薪资较低 所以显
  • openssl在windows环境和linux环境中的使用问题

    场景 使用c程序调用openssl在windows上进行加密 加密之后的结果放到linux环境中使用 问题 发现在windows中加密之后的密码 在linux环境中使用openssl进行解密得到的结果与加密之前不符 原因 发现是window
  • 第三章 信息系统资源管理

    信息系统资源管理概述 信息系统资源管理 为完成信息系统资源的合理开发和高效利用 保证优质的信息系统上线 并能发挥信息系统在企业运行中的重要作用所采取的一系列管理措施 信息系统基本概念 信息系统 IS 信息系统是一个完成信息采集 传递 存储
  • Clion2021的安装并实现stm32F103点亮LED

    CLion是Jetbrains公司旗下新推出的一款专为开发C C 所设计的跨平台IDE 它是以IntelliJ为基础设计的 同时还包含了许多智能功能来提高开发人员的生产力 CLion专为使用C和C 以及 Kotlin Native Rust
  • Vue经典面试题 ,为什么组件中的data是一个函数而不是一个对象

    为什么vue组件中的data是一个函数 官方解析 Vue 实例的数据对象 Vue 会递归地把 data 的 property 转换为 getter setter 从而让 data 的 property 能够响应数据变化 当一个组件被定义 d
  • 【电力电子技术】全桥 半桥 推挽 双管正激 DC-DC

    BUCK BOOST BUCK BOOST CUK SEPIC ZETA 二象限 四象限 多重多相DCDC FLYBACK FORWARD 全桥 半桥 推挽 双管正激 DC DC CURRENT DOUBLER
  • IEEE-754 64位双精度浮点数存储详解

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