IEEE754,浮点数的精度

2023-10-13 07:18
文章标签 浮点数 精度 ieee754

本文主要是介绍IEEE754,浮点数的精度,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://zh.wikipedia.org/wiki/IEEE_754


IEEE二进制浮点数算术标准IEEE 754)是1980年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。

IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80比特实做)。只有32位模式有强制要求,其他都是选择性的。大部分编程语言都有提供IEEE浮点数格式与算术,但有些将其列为非必需的。例如,IEEE 754问世之前就有的C语言,现在有包括IEEE算术,但不算作强制要求(C语言的float通常是指IEEE单精确度,而double是指双精确度)。

该标准的全称为IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985),又称IEC 60559:1989,微处理器系统的二进制浮点数算术(本来的编号是IEC 559:1989)[1]。后来还有“与基数无关的浮点数”的“IEEE 854-1987标准”,有规定基数为2跟10的状况。现在最新标准是“IEEE 854-2008标准”。

在六、七十年代,各家计算机公司的各个型号的计算机,有着千差万别的浮点数表示,却没有一个业界通用的标准。这给数据交换、计算机协同工作造成了极大不便。IEEE的浮点数专业小组于七十年代末期开始酝酿浮点数的标准。在1980年,英特尔公司就推出了单片的8087浮点数协处理器,其浮点数表示法及定义的运算具有足够的合理性、先进性,被IEEE采用作为浮点数的标准,于1985年发布。而在此前,这一标准的内容已在八十年代初期被各计算机公司广泛采用,成了事实上的业界工业标准。

目录

  • 1 浮点数剖析
    • 1.1 本文表示比特的约定
    • 1.2 整体呈现
      • 1.2.1 指数偏移值
      • 1.2.2 规约形式的浮点数
      • 1.2.3 非规约形式的浮点数
      • 1.2.4 特殊值
      • 1.2.5 32位单精度
      • 1.2.6 64位双精度
    • 1.3 浮点数的比较
    • 1.4 浮点数的舍入
    • 1.5 浮点数的运算与函数
      • 1.5.1 标准运算
    • 1.6 建议的函数与谓词
  • 2 外部链接
  • 3 参考文献

浮点数剖析

以下是该标准对浮点数格式的描述。

本文表示比特的约定

把W个比特(bit)的数据,从内存地址低端到高端,以0到W−1编码。通常将内存地址低端的比特写在最右边,称作最低有效位(least significant bit或lsb),代表最小的比特,改变时对整体数值影响最小的比特。声明这一点的必要性在于X86体系架构是小端序的数据存储。

对于十进制整数N,必要时表示为N10以与二进制的数的表示N2相区分。

对于一个数,其二进制科学计数法表示下的指数的值,下文称之为指数的实际值;而根据IEEE 754标准对指数部分的编码的值,称之为浮点数表示法指数域的编码值

整体呈现

IEEE 754浮点数的三个域

二进制浮点数是以符号数值表示法的格式存储——最高有效位被指定为符号位(sign bit);“指数部份”,即次高有效的e个比特,存储指数部分;最后剩下的f个低有效位的比特,存储“尾数”(significand)的小数部份(在非规约形式下整数部份默认为0,其他情况下一律默认为1)。

指数偏移值

指数偏移值(exponent bias),是指浮点数表示法中的指数域的编码值为指数的实际值加上某个固定的值,IEEE 754标准规定该固定值为 2e-1 - 1[2],其中的e为存储指数的比特的长度。

以单精度浮点数为例,它的指数域是8个比特,固定偏移值是28-1 - 1 = 128−1 = 127. 单精度浮点数的指数部分实际取值是从128到-127。例如指数实际值为1710,在单精度浮点数中的指数域编码值为14410, 即14410 = 1710 + 12710.

采用指数的实际值加上固定的偏移值的办法表示浮点数的指数,好处是可以用长度为e个比特的无符号整数来表示所有的指数取值,这使得两个浮点数的指数大小的比较更为容易。

规约形式的浮点数

如果浮点数中指数部分的编码值在0 < exponent < 2^{e} - 1之间,且尾数部分最高有效位(即整数字)是1,那么这个浮点数将被称为规约形式的浮点数

非规约形式的浮点数

如果浮点数的指数部分的编码值是0,尾数为非零,那么这个浮点数将被称为非规约形式的浮点数。IEEE 754标准规定:非规约形式的浮点数的指数偏移值比规约形式的浮点数的指数偏移值大1. 例如,最小的规约形式的单精度浮点数的指数部分编码值为1,指数的实际值为-126;而非规约的单精度浮点数的指数域编码值为0,对应的指数实际值也是-126而不是-127。实际上非规约形式的浮点数仍然是有效可以使用的,只是它们的绝对值已经小于所有的规约浮点数的绝对值;即所有的非规约浮点数比规约浮点数更接近0。规约浮点数的尾数大于等于1且小于2,而非规约浮点数的尾数小于1且大于0.

IEEE 754-1985标准采用非规约浮点数,源于70年代末IEEE浮点数标准化专业技术委员会酝酿浮点数二进制标准时,Intel公司对渐进式下溢出(gradual underflow)的力荐。当时十分流行的DEC VAX机的浮点数表示采用了突然式下溢出(abrupt underflow). 如果没有渐进式下溢出,那么0与绝对值最小的浮点数之间的距离(gap)将大于相邻的小浮点数之间的距离。例如单精度浮点数的绝对值最小的规约浮点数是1.0\times 2^{-126}, 它与绝对值次小的规约浮点数之间的距离为2^{-126}\times 2^{-23}=2^{-149}。如果不采用渐进式下溢出,那么绝对值最小的规约浮点数与0的距离是相邻的小浮点数之间距离的2^{23}倍!可以说是非常突然的下溢出到0。这种情况的一种糟糕后果是:两个不等的小浮点数X与Y相减,结果将是0. 训练有素的数值分析人员可能会适应这种限制情况,但对于普通的程序员就很容易陷入错误了。采用了渐进式下溢出后将不会出现这种情况。例如对于单精度浮点数,指数部分实际最小值是(-126),对应的尾数部分从1.1111\ldots 11, 1.1111\ldots 10一直到0.0000\ldots 02, 0.0000\ldots 01,相邻两小浮点数之间的距离(gap)都是2^{-126}\times 2^{-23}=2^{-149};而与0最近的浮点数(即最小的非规约数)也是2^{-126}\times 2^{-23}=2^{-149}

特殊值

这里有三个特殊值需要指出:

  1. 如果 指数 是0 并且尾数的 小数部分 是0,这个数±0(和符号位相关)
  2. 如果 指数 = 2^{e} - 1 并且尾数的 小数部分 是0,这个数是 ±∞(同样和符号位相关)
  3. 如果 指数 = 2^{e} - 1 并且尾数的 小数部分 非0,这个数表示为不是一个数(NaN)。

以上规则,总结如下:

形式指数小数部分
00
非规约形式0非0
规约形式12^e-2任意
无穷2^e-10
NaN2^e-1非零
32位单精度

单精度二进制小数,使用32个比特存储。

1823 位长
SExpFraction
3130至23
偏正值 (实际的指数大小+127)
22至0 位编号(从右边开始为0)

S为符号位,Exp为指数字,Fraction为有效数字。 指数部分即使用所谓的偏正值形式表示,偏正值为实际的指数大小与一个固定值(32位的情况是127)的和。采用这种方式表示的目的是简化比较。因为,指数的值可能为正也可能为负,如果采用补码表示的话,全体符号位S和Exp自身的符号位将导致不能简单的进行大小比较。正因为如此,指数部分通常采用一个无符号的正数值存储。单精度的指数部分是−126~+127加上偏移值127 ,指数值的大小从1~254(0和255是特殊值)。浮点小数计算时,指数值减去偏正值将是实际的指数大小。

单精度浮点数各种极值情况:

类别正负号实际指数有偏移指数指数域尾数域数值
0-12700000 0000000 0000 0000 0000 0000 00000.0
负零1-12700000 0000000 0000 0000 0000 0000 0000−0.0
1001270111 1111000 0000 0000 0000 0000 00001.0
-1101270111 1111000 0000 0000 0000 0000 0000−1.0
最小的非规约数*-12600000 0000000 0000 0000 0000 0000 0001±2−23 × 2−126 = ±2−149 ≈ ±1.4×10-45
中间大小的非规约数*-12600000 0000100 0000 0000 0000 0000 0000±2−1 × 2−126 = ±2−127 ≈ ±5.88×10-39
最大的非规约数*-12600000 0000111 1111 1111 1111 1111 1111±(1−2−23) × 2−126 ≈ ±1.18×10-38
最小的规约数*-12610000 0001000 0000 0000 0000 0000 0000±2−126 ≈ ±1.18×10-38
最大的规约数*1272541111 1110111 1111 1111 1111 1111 1111±(2−2−23) × 2127 ≈ ±3.4×1038
正无穷01282551111 1111000 0000 0000 0000 0000 0000+∞
负无穷11282551111 1111000 0000 0000 0000 0000 0000−∞
NaN*1282551111 1111non zeroNaN
* 符号位可以为0或1 .
64位双精度

双精度二进制小数,使用64个比特存储。

11152 位长
SExpFraction
6362至52
偏正值 (实际的指数大小+1023)
51至0 位编号(从右边开始为0)

S 为符号位,Exp为指数字,Fraction为有效数字。 指数部分即使用所谓的偏正值形式表示,偏正值为实际的指数大小与一个固定值(64位的情况是1023)的和。采用这种方式表示的目的是简化比较。因为,指数的值可能为正也可能为负,如果采用补码表示的话,全体符号位S和Exp自身 的符号位将导致不能简单的进行大小比较。正因为如此,指数部分通常采用一个无符号的正数值存储。双精度的指数部分是−1022~+1023加上1023 ,指数值的大小从1~2046(0(2进位全为0)和2047(2进位全为1)是特殊值)。浮点小数计算时,指数值减去偏正值将是实际的指数大小。

浮点数的比较

浮点数基本上可以按照符号位、指数域、尾数域的顺序作字典比较。显然,所有正数大于负数;正负号相同时,指数的二进制表示法更大的其浮点数值更大。

浮点数的舍入

任何有效数上的运算结果,通常都存放在较长的暂存器中,当结果被放回浮点格式时,必须将多出来的比特丢弃。 有多种方法可以用来运行舍入作业,实际上IEEE标准列出4种不同的方法:

  • 舍入到最接近:会将结果舍入为最接近且可以表示的值。这是缺省的近似方法。
  • 朝+∞方向舍入:会将结果朝正无限大的方向舍入。
  • 朝-∞方向舍入: 会将结果朝负无限大的方向舍入。
  • 朝0方向舍入: 会将结果朝0的方向舍入。

浮点数的运算与函数

标准运算

下述函数必须提供:

  • 加减乘除 Add, subtract, multiply, divide. 在加减运算中负零与零相等 -0.0 = 0.0
  • 平方根 Square root. sqrt(x) ≥ 0 (x≥0), 另规定 sqrt(-0.0) = -0.0
  • 浮点余数. 返回值 x - (round(x / y) * y).
  • 近似到最近的整数 round(x). 如果恰好在两个相邻整数之间,则近似到偶数.
  • 比较运算. -Inf < 负的规约浮点数数 < 负的非规约浮点数 < -0.0 = 0.0 < 正的非规约浮点数 < 正的规约浮点数 < Inf;

  特殊比较: -Inf = -Inf, Inf = Inf, NaN 与任何浮点数(包括自身)的比较结果都为假,即 (NaN ≠ x) = false.

建议的函数与谓词

  • copysign(x, y): copysign(x, y) 返回的值由 x 的不带符号的部份和 y 的符号组成。因此 abs(x) 等于 copysign(x, 1.0)copysign 可以对 NaN 正确操作,这是少有的几个可以对 NaN 像普通算术一样操作有效的函数之一。C99 新增了 copysign 函数.
  • −x: 从涵义上指将 x 的符号反转. 当 x 是 ±0 或者 NaN 时,其涵义可能不同于 0-x.
  • scalb(y, N): 计算 y×2N (N 是整数), 无需再计算 2N。C99 中对应的函数名是scalbn.
  • logb(x): 计算 x = 1.a×2n (x ≠ 0, a ∈[0, 1) ) 中的 n. C99 新增了 logbilogb 函数.
  • nextafter(x,y): 沿 y 方向找最邻近 x 的可表达浮点数。比如 nextafter(0, 1) 得到的是最小可表达的正数。C99 新增了 nextafter 函数.
  • finite(x): 判断 x 是否有限,即 −Inf < x < Inf. C99 新增了 isfinite 函数.
  • isnan(x): 判断 x 是否是一个 NaN,这等价于 "x ≠ x". C99 新增了 isnan 函数.
  • x <> y: 仅当 x < y 或者 x > y 时才为 True,其涵义是 NOT(x = y)。注意这不同于 "x ≠ x"。
  • unordered(x, y): 当 x 与 y 无法比较大小时为 True,比如说 x 或者 y 是一个 NaN. C99 中对应的函数名是 isunordered.
  • class(x): 区分 x 的浮点数类属:信号NaN、静默NaN、-Inf、负的规约浮点数,负的非规约浮点数,-0.0,0.0,正的非规约浮点数,正的规约浮点数,Inf。

这篇关于IEEE754,浮点数的精度的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/201614

相关文章

单精度浮点数按存储格式转为整数的程序

///#include<cstdio>//-----------------union int_char{unsigned char ch[4];float i;};void out_put(union int_char x)//x86是小端对其模式,即最数据的最低位存储在地址的最低位上。{printf("单精度浮点数值为:%f\n",x.i,x.i);printf("存储位置从左到右

从计组中从重温C中浮点数表示及C程序翻译过程

目录 移码​编辑  传统浮点表示格式 浮点数的存储(ieee 754)->修炼内功 例子:   ​编辑 浮点数取的过程   C程序翻译过程 移码  传统浮点表示格式 浮点数的存储(ieee 754)->修炼内功 根据国际标准IEEE(电⽓和电⼦⼯程协会)  32位 例子:    64位    IEEE754对有效数字M和

《长得太长也是错?——后端 Long 型 ID 精度丢失的“奇妙”修复之旅》

引言 在前后端分离的时代,我们的生活充满了无数的机遇与挑战——包括那些突然冒出来的让人抓狂的 Bug。今天我们要聊的,就是一个让无数开发者哭笑不得的经典问题:后端 Long 类型 ID 过长导致前端精度丢失。说到这个问题,那可真是“万恶之源”啊,谁让 JavaScript 只能安全地处理 Number.MAX_SAFE_INTEGER(也就是 9007199254740991)以内的数值呢?

IEEE的浮点数表示

IEEE浮点标准用V=(-1)^s*M*2^E 由符号,尾数,阶码表示 32位单精度 单精度 二进制小数,使用32位存储。 1 8 23 位长 +-+--------+-----------------------+ |s| exp | fraction | +-+--------+-----------------------+ 31 30 23 22 0 位

关于精度的问题

在一些问题中经常会遇到一些关于精度的保留; 1.要求保留小数后n位小数:代码如下 #include<stdio.h>int main(){double num = 1.123456789;int n = 6;printf("%0.*lf\n",n,num);    //1.123457return 0;} 注意,他会在小数点第n+1位四舍五入; 2.要求截取小数后n位,也就是不四舍五

蓝牙技术|超高精度蓝牙位置服务将成为蓝牙定位产品发展方向

随着市场需求的变化,精确的距离测量成为提升安全性和用户体验的重要因素。预计未来五年蓝牙位置服务设备的年均增长率为22%,到2028年出货量将达到5.63亿台。 为了满足这一需求,SIG即将在2024年下半年推出一项新功能——蓝牙信道探测(Bluetooth Channel Sounding)。这项新技术基于相位测量(PBR)和往返时间(RTT)两种测距方式,为蓝牙设备带来安全且精确的测距功能。

PointNet++改进策略 :模块改进 | PAConv,位置自适应卷积提升精度

题目:PAConv: Position Adaptive Convolution with Dynamic Kernel Assembling on Point Clouds来源:CVPR2021机构:香港大学论文:https://arxiv.org/abs/2103.14635代码:https://github.com/CVMI-Lab/PAConv 前言 PAConv,全称为位置自适应卷积

【matlab】双精度每字符占8字节,单精度每字符占4字节

>> help magicmagic - Magic squareThis MATLAB function returns an n-by-n matrix constructed from the integers 1through n^2 with equal row and column sums.M = magic(n)magic 的参考页另请参阅 ones, rand>> a = ma

C语言浮点数运算,讲述原理并总结一些案例

有些C语言书上说float型的有效位数是6~7位,为什么不是6位或者7位?而是一个变化的6~7位?         浮点数在内存中是如何存放的?         float浮点数要比同为4字节的int定点数表示的范围大的多,那么是否可以使用浮点数替代定点数?         为什么float型浮点数9.87654321 > 9.87654322不成立?为何10.2 - 9的结果不

YoloV10改进策略:卷积篇|基于PConv的二次创新|附结构图|性能和精度得到大幅度提高(独家原创)

文章目录 摘要论文指导PConv在论文中的描述改进YoloV10的描述 改进代码与结构图改进方法测试结果总结 摘要 在PConv的基础上做了二次创新,创新后的模型不仅在精度和速度上有了质的提升,还可以支持Stride为2的降采样。 改进方法简单高效,需要发论文的同学不要错过! 论文指导 PConv在论文中的描述 论文: 下面我们展示了可以通过利用特征图的冗余来进一步优化成本