IEEE Standard 754浮点数介绍

本文翻译自,并做补充:

https://steve.hollasch.net/cgindex/coding/ieeefloat.html

 

IEEE Standard 754是当下在计算机中描述实数最通用的一种方式,计算机包括英特尔系列的电脑,苹果公司的麦金塔电脑以及绝大多数Unix平台的电脑。本文给出了IEEE浮点数的描述,关于算法部分的实现可以参考文章末尾提供的参考资料。

 

什么是浮点数?

在计算机上描述实数的方法有很多。固定点在数字中间的某处放置一个小数点,相当于使用整数来表示单位的一部分,比如可以用1来表示一个单位的1/100。如果有4位数字,你可以表示10.82或者00.01。另外一种方法是使用有理数的形式,通过两个整数的比例来表示每一个数字。

浮点描述法,最通用的方法,由一个基数和一个指数组成,使用科学计数法来表示数字。比如123.456可以表示成1.23456 × 10^2。如果使用16进制,数字123.abc表示成1.23abc × 16^2。如果使用二进制,10100.110表示成1.0100110 × 2^4。

浮点描述解决了很多问题,固定点在描述上有一定限制,比如很大或者很小的数字不好描述。同时,固定点在连个很大的数值相除时会损失精度。

另一方面,浮点采用浮动方式采用合适的精度表示数字比例规模。它可以非常容易地描述从1,000,000,000,000 到 0.0000000000000001之间的数值,兼顾数值的精度和比例规模。

 

存储布局

IEEE浮点数由三个部分组成:符号位,指数和尾数。尾数由分数部分和隐式数字组成,指数的基数(2)是隐藏的,不需要存储。

下面这个表显示了单精度(32bit)和双精度(64bit)浮点数的布局。数字的每一个比特位都表示了出来,方括号中的数值表示了比特位的范围。00表示最低有效位。

浮点组成部分

 

符号(S)

指数(E)

尾数(F)

单精度

1[31]

8[30-23]

23[22-00]

双精度

1[63]

11[62-52]

52[51-00]

以位的形式排列,浮点数看起来是这样的:

Single: SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF

Double: SEEEEEEE EEEEFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

 

符号位

符号位非常简单:0表示正数,1表示负数。翻转此位的值将翻转数字的符号。

 

指数部分

指数字段需要同时表示正指数和负指数。为此,需要向实际的指数添加一个偏差,以获得最终需要存储的指数。对于IEEE单精度浮点数,这个值是127。因此,为了表示指数为0,将127存储在指数字段中。存储值200表示指数(200−127)或73。出于后面讨论的原因,−127(都是0)和+128(都是1)的指数被保留给特殊的数字。

双精度有一个11位的指数字段,偏差为1023。

 

尾数部分

尾数,也称为有效数,表示数字的精确位。它由隐式前导位(小数点左边)和小数位(小数点右边)组成。

要找出隐含的前导位的值,请考虑任何数字都可以用科学符号以许多不同的方式表示。例如,数字50可以用以下任何一种表示:

0.050 × 10^3

.5000 × 10^2

5.000 × 10^1

50.00 × 10^0

 5000. × 10^−2

为了最大化可表示数的数量,浮点数通常以规范化的形式存储。这基本上是把小数点放在第一个非零位之后。在标准表达式中,50表示为5.000×10^1。

现在,我们可以在以2为基底的情况下进行一个小小的优化,因为二进制只有一个可能的非零位:1。因此,我们可以假设前导数字为1,而不需要将其存储在浮点表示中。因此,我们可以假设前导位为1而不存储它,这样一个32位浮点值实际上有24位尾数:23个显式分数位加上一个隐式前导位1。

 

把它们放在一起

综上所述:

(1)符号位。正数位是0,负数是1。

(2)指数的基数是2。

(3)指数字段单精度需要加上127得到最终指数,或双精度需要加上1023得到最终指数。

(4)尾数的第一个位通常被假定为1,从而产生一个完整的尾数为1.f,f是其分数部分。

 

浮点数的范围

让我们考虑一下单精度浮点数。我们基本上采用了一个32位的数字,并重新解释字段以覆盖更广泛的范围。有些东西必须要放弃,那就是精确度。例如,一般的32位整数,其精度都在0附近,可以精确地存储具有32位分辨率的整数。另一方面,单精度浮点数无法与它的24位匹配这种分辨率。但是,它通过有效地从低端截断并四舍五入来近似这个值。例如:

11110000 11001100 10101010 10101111 // 32位整数

=   +1.1110000 11001100 10101011 x 2^31 //单精度浮点

=    11110000 11001100 10101011 00000000 //实际浮点值

这近似于32位的值,但不能产生精确的表示。另一方面,除了能够表示小数部分(整数完全没有)之外,浮点值可以表示2^127左右的数字,而32位整数的最大值是2^32左右。

正浮点数的范围可以分为正规化数(保持尾数的完全精度)和非正规化数(假定前导数字为0,稍后将讨论),后者只使用小数部分的精度的一部分。

浮点范围

 

非正规化

正规化

近似的小数

单精度

±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^−1074 ~ (1−2^−52)×2^−1022

± ≈10^−323.3 ~ ≈10^308.3

由于每个浮点数都有一个对应的负值(通过切换符号位),所以上面的范围都是围绕0对称的。

单精度浮点数到目前为止的方案还不能代表五个不同的数值范围:

(1)负数小于-(2−2^−23)×2^127(负上溢出)

(2)负数大于−2^−149(负下溢出)

(3)零

(4)正数小于2^−149(正下溢出)

(5)正数大于(2−2^−23)×2^127(正上溢出)

上溢出指的是值的增长对于表示来说太大了,就像溢出整数一样。下溢出是一个不那么严重的问题,因为是表示精度的损失,它可以保证接近于零。

有限的IEEE浮点数的总有效范围表如下:

有效浮点范围

 

二进制

十进制

单精度

± (2−2^−23) × 2^127

≈ ± 10^38.53

双精度

± (2−2^−52) × 2^1023

≈ ± 10^308.25

注意,当有限数的指数为最大值(单精度为2^127,双精度为2^1023),尾数为1(包括规范化的1位)时,就会出现极值(无论符号如何)。

 

特殊值

IEEE保留所有0和1的指数字段值,以表示浮点方案中的特殊值。

非正规化

如果指数都是0,那么值就是一个非正规化的数字,现在假定在二进制点前有一个前导0。因此,它表示一个数(−1)^s×0.f×2^−126,其中s为符号位,f为分数。对于双精度,非正规化数的形式为(−1)^s×0.f×2^−1022。

当非正规化的数字变得更小时,它们会逐渐失去精度,因为分数的左位变成了零。在最小的非零非正规化值上(只有最不重要的部分位是1),32位浮点数与标准的24位规范化值相比只有一个位的精度。

可以把零看作是一个非正规化的数字(隐含的前导0位),它包含所有的0位小数。请注意,−0和+0是不同的值,虽然它们都比较起来是相等的。

无穷

值的正无穷和负无穷用所有1的指数和所有0的分数表示。符号位区分负无穷和正无穷。能够将无穷大表示为一个特定的值是有用的,因为它允许操作在溢出情况下继续进行。无穷数运算在IEEE中定义得很好。

非数值

值NaN(不是数字)用于表示不代表实数的值。NaN由一个具有所有1的指数和一个非零分数的位模式表示。有两类NaN: QNaN(Quiet NaN)和SNaN(Signalling NaN)。

QNaN是具有最有效分式位的NaN。QNaN可以自由地参与大多数算术运算。这些值是在结果没有数学定义的情况下由操作生成的。

SNaN是一个具有最显著位清晰的NaN。在操作中使用时,可以使用它来发出异常信号。SNaN可以方便地赋值给未初始化的变量,以避免过早使用。

在语义上,QNaN的表示不确定操作,而SNaN的表示无效操作。

 

特殊运算

IEEE定义了特殊数上的运算。在最简单的情况下,使用NaN的任何操作都会产生NaN结果。其他操作如下:

特殊的运算结果

运算符

结果

n ÷ ±∞

0

±∞ × ±∞

±∞

±nonZero ÷ ±0

±∞

±finite × ±∞

±∞

∞ + ∞

∞ − −∞

+∞

−∞ − ∞

−∞ + −∞

−∞

∞ − ∞

−∞ + ∞

NaN

±0 ÷ ±0

NaN

±∞ ÷ ±∞ 

NaN

±∞ × 0

NaN

NaN == NaN

false

 

总结

综上所述,对于给定的表示,对应的值如下:

浮点值(b = bias)

符号

指数(e)

分数(f)

0

00⋯00

00⋯00

+0

0

00⋯00

00⋯01

11⋯11

正非规范化实数

0.f × 2(−b+1)

0

00⋯01

11⋯10

XX⋯XX

正规范化实数

1.f × 2(eb)

0

11⋯11

00⋯00

+∞

0

11⋯11

00⋯01

01⋯11

SNaN

0

11⋯11

1X⋯XX

QNaN

1

00⋯00

00⋯00

−0

1

00⋯00

00⋯01

11⋯11

负非规范化实数

−0.f × 2(−b+1)

1

00⋯01

11⋯10

XX⋯XX

负规范化实数

−1.f × 2(e−b)

1

11⋯11

00⋯00

-∞

1

11⋯11

00⋯01

01⋯11

SNaN

1

11⋯11

11⋯11

QNaN

引用

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值