1. 定点数(Fixed Point Number)
2. 浮点数(Floating Point Number)

3. IEEE 754 标准

  3.1 什么是 IEEE 754
  3.2 IEEE 754 由来
  3.3 IEEE 754 构成
  3.4 IEEE 754 格式及编码

(1)单精度浮点格式(32位)
(2)双精度浮点格式(64位)

  3.5 格式化值与非格式化值

(1)格式化值
(2)非格式化值
(3)特殊数值

  3.6 舍入误差

1. 定点数(Fixed Point Number)


  在计算机系统的发展过程中,业界曾经提出过许多种实数的表达方法,比较典型的是定点数。

  在定点数表达法中,其小数点固定地位于实数所有数字中间的某个位置。例如,货币的表达就可以采用这种表达方式,如 55.00 或者 00.55 可以用于表达具有4位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用 4 位数值来表达相应的数值。

  但我们不难发现,定点数表达法的缺点就在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。因此,最终绝大多数现代的计算机系统都采纳了所谓的浮点数表达法。

2. 浮点数(Floating Point Number)


  浮点数表达法采用了科学计数法来表达实数,即用一个有效数字(Significant)一个基数(Base)一个指数(Exponent)以及一个表示正负的符号(Sign)来表达实数。比如,123.45用十进制可以表达为 1.2345×102——其中,1.2345 为有效数字,10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。其中,有效数字有时也称为尾数(Mantissa)

  当然,对实数的浮点表示仅作如上的规定是不够的的,因为同一实数的浮点表示还不是唯一的。123.45 同样也可以表达为 0.12345×103 和 12.345×101这两种方式。正是因为这种表达的多样性,因此有必要对其加以规范以达到统一表达的目的。

  规范的浮点数表达方式具有如下形式:

其中,d.dd…d为有效数字,β为基数,e为指数。

  有效数字中数字的个数称为精度,可以用 p 来表示有效数字精度。有效数字中的每个数字 d 介于 0(包括0) 和基数 β 之间,更精确地说,

表示以下数:

  其中,对十进制的浮点数,即基数 β 等于 10 的浮点数而言,如 12.345 可以表达为:1×102+2×101+3×100+4×10-1+5×10-2,则该十进制的浮点数的规范浮点数表达为 1.2345×101

  同样地,对于二进制也可以如此简单地表达。唯一不同之处在于:二进制的 β 等于2,而每个数字 d 只能在 0 和 1 之间取值。如 1001.101,我们可以根据上面的表达式表达为:1×23+0×22+0×21+1×20+1×2-1+0×2-2+1×2-3,则该二进制的浮点数的规范浮点数表达为:1.001101×23

  另外,对于十进制数,我们知道小数点每向左移动一位,就相当于这个十进制数除以 10 ;每向右移动一位,就相当于乘以 10。如 12.345,小数点向左移动一位时为 1.2345,除以了 10;小数点向右移动一位时为 123.45,乘以了 10。

  同样地,对于二进制数,小数点每向左移动一位,相当于这个二进制数除以2;小数点每向右移动一位,就相当于乘以2。关于这个定理的证明可以从下面的表达式推出,不再赘述。

  除此之外,我们还可以得到这样一个基本规律:一个十进制小数要能用浮点数精确地表示,最后一位小数必须是5。当然,这不是必要条件,而不是充分条件。也就是说,不能推出一个最后一位小数是 5 的十进制小数必定能用浮点数精确地表示。下面证明必要条件:

  十进制数转换成二进制数规则:整数部分除以 2,直至商为 0,否则将得到的商继续除以 2,结果取逆序的余数; 小数部分乘以 2,直至乘积为 1,否则将得到的乘积继续乘以 2,结果取顺序的整数

如把十进制 (13.125)10二进制数:


整数部分 整数结果为:(13)10=(1101)2


小数部分 小数结果为:(0.125)10=(001)2


因此,结果是:(13.125)10=(1101.001)2

  从十进制转二进制的规则来看,我们可以这样理解:小数部分乘以 2 直至乘积为1结束。而在 (0.1)10 到 (0.9)10这 9 个小数中,只有 0.5 可以精确表示:(0.5)10 =(0.1)2

  同样地,从二进制数向十进制数转换的规则(按权相加法:整数部分最后一个权为 20,往前推依次乘以 2,往后推依次乘以 2-1。如 (1101.001)2=1×23+1×22+0×21+1×20+0×2-1+0×2-2+1×2-3)来看:

  从前面的结论我们可以知道,对于一个初始二进制的数 1,将其小数点每向右移动一位时,都相当于将它对应的十进制除以 2,因此二进制的小数能转换的十进制结果最后一位数必定是5。

3. IEEE 754 标准


3.1 什么是 IEEE 754

  IEEE 二进制浮点数算术标准(IEEE 754)是 20 世纪 80 年代以来最广泛使用的浮点数运算标准,为许多 CPU 与浮点运算器所采用。

  这个标准定义了表示浮点数的格式(包括负0)与反常值(denormal number)、一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的 "浮点运算符";它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。

3.2 IEEE 754 由来

  直到 20 世纪 80 年代(即在制定 IEEE 754 标准之前),业界还没有一个统一的浮点数标准。相反,很多计算机制造商根据自己的需要来设计自己的浮点数表示规则和浮点数的执行运算细节,而且,他们常常并不太关注运算的精确性,而把实现的速度和简易型看得比数字的精确性更重要,这给代码的可移植性造成了重大的障碍。

  直到 1976年,Inter 公司打算为其 8086微处理器引进一种浮点数协处理器时,意识到作为芯片设计者的电子工程师和固体物理学家也许并不能通过数值分析来选择最合理的浮点数二进制格式。于是,他们邀请加州大学伯克利分校的 William Kahan 教授(当时最优秀的数值分析家)来为 8087 浮点处理器(FPU)设计浮点数格式。

  后来,William Kahan 教授又找来两个专家协助他,于是就有了 KCS 组合(Kahan、COOnan 和 Stone),他们共同完成了 Intel 公司的浮点数格式设计。

  由于 Intel 公司的 KCS 浮点数格式完成得如此出色,以致 IEEE(Institue of Electrical and Electronics Engineers,电子电气工程师协会) 决定采用一个非常接近 KCS 的方案作为 IEEE 的标准浮点格式,Kahan 教授也因此获得了 1987 年的图灵奖,同时也被誉为 "浮点数之父"。

  在 8087 浮点处理器的基础上,IEEE 于 1985年制订了二进制浮点运算标准 IEEE 754 (IEEE Standard for Binary Floating-Point Arithmetic,ANSI/IEEE Std 754-1985),该标准限定指数的底为2,并于同年被美国引用为 ANSI 标准。目前,几乎所有的计算机都支持 IEEE 754 标准,它大大地改善了科学应用程序的可移植性。

  考虑到 IBM System/370 的影响,IEEE 于 1987 年推出了与底数无关的二进制浮点运算标准 IEEE 854,并于同年被美国引用为 ANSI 标准。1989 年,国际标准组织 IEC 批准 IEEE 754/854 为国际标准 IEC 559:1989。后来经修订后,标准号改为 IEC 60559.现在,几乎所有的浮点处理器完全或基本支持 IEC 60559。

3.3 IEEE 754 构成

  IEEE 浮点数标准是从逻辑上用三元组 {S, E, M} 来表示一个数 V 的,即 V = (-1) S × M × 2 E,如下图所示:

  符号位 S (Sign):决定数是正数(s = 0)还是负数(s = 1),而对于数值 0 的符号位解释则作为特殊情况处理。

  指数位 E (Exponent):是2 的幂(可能是负数),表示数 V 的指数位,它的作用是对浮点数加权;采用移位存储(下文详述)。

  有效数字位 M (Significant):是二进制小数,也被称为尾数位 (Mantissa)、系数位 (Coefficient),甚至还被称作 "小数"。

3.4 IEEE 754 格式及编码

IEEE 754 标准准确地定义了单精度和双精度浮点格式,并为这两种格式分别定义了扩展格式,如下所示:

  • 单精度浮点格式(32位)
  • 双精度浮点格式(64位)
  • 扩展单精度浮点格式(≥ 43位,不常用)
  • 扩展双精度浮点格式(≥ 79位,一般情况下,Intel x86结构的计算机采用的是 80 位,而 SPARC 结构的计算机采用的是 128 位)

  上述格式中只有 32 位格式有强制要求,其他都是选择性的。大部分编程语言都提供了 IEEE 浮点数格式与算术,但有些将其列为非必需的。例如,IEEE 754 问世之前的 C 语言,现在虽然包括了 IEEE 算术,但不算作强制要求(C 语言的 float 通常是指 IEEE 单精度,而 double 是指双精度)。

(1)单精度浮点格式(32位)

其中,符号位 S 占 1 位,指数位 E 占 8 位, 有效数字位 M 占 23 位。

  如上图,32 位中的第 0 位存放小数段的最低有效位 LSB(Least Significant Bit),第 22 位存放小数段的最高有效位 MSB(Most Significant Bit);第 23 位存放指数段的 LSB,第 30 位 存放指数段的 MSB;最高位,即第 31 位存放符号 S。

(2)双精度浮点格式(64位)

其中,符号位 S 占 1 位,指数位 E 占 11 位, 有效数字位 M 占 52 位。

  在 Inter x86 结构的计算机中,数据存放采用的是小端法 (Little Endian),故较低地址的 32 位 的字中存放小数段的 [31:0] ,而在 SPARC 结构的计算机中,因其数据存放采用的是大端法 (Big Endian),故较高地址的 32 位字中存放小数段的 [31:0]。


  值得注意的是,有效数字位 M 虽然是 23 位(或者双精度浮点格式的 52 位),但是因为规格化一个浮点数时,任何一个二进制数的科学计数法表示都为 1. xxx × 2n,而由于第一位总是等于1,因此我们就不需要显式地表示它。这样,我们上面所说的有效数字位其实包括了一个隐藏位 1并不会存储(在非规约形式下整数部分默认为 0,其他情况下一律默认为 1,下文详述)。因此 ,23 / 52 位的有效数字位 M 只是表示小数点之后的二进制位数,而可以表示的二进制的精度也就变成了 24 / 53 位。(前文已提及,有效数字中数字的个数称为精度)对应十进制精度时,单精度浮点型精度为 log224 = 7.22,双精度浮点型精度为 log253 = 15.95。关于这个算法,以单精度浮点型为例,因为 2(23+1) = 16777216 ∈ (107, 108),所以得到单精度浮点数的有效位数是 7 位。

  而对于指数部分 E,我们知道,指数可以为正数,也可以为负数。为了处理负数的情况,规定了一个指数偏移值(exponent bias),即浮点数表示法中指数域的编码值,等于指数的实际值(二进制科学计数法表示下的指数的值)加上某个固定的值。IEEE 754 标准规定该固定值为 2e-1 - 1,其中 e 为存储指数的比特的长度。

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

  以单精度浮点数为例,它的指数域是 8 位,因此固定偏移值就为 28-1 - 1 = 128 -1 = 127。作为无符号数时,其取值范围为 0000 0000 ~ 1111 1111,即 0 ~ 255,但是0 和 255 作为了特殊用途 (见下文 "非规约形式的浮点数" 和 "特殊值"),因此对应的单精度浮点数的指数部分实际取值是 (1 ~ 254) - 127 即-126~127(此时 0 和 255 分别对应的 -127 和 128 被用作特殊值)。例如指数实际值为 (17)10,在单精度浮点数中的指数域编码为 (144)10,即(144)10 = (17)10 + (127)10。这就是上文提到的移位存储。

  以单精度数 9.625 为例,将其转换成二进制为 1001.101,其规范浮点数为 1.001101 × 23,所以实际保存在有效数字位中的 23 位值为:

0011 0100 0000 0000 0000 000

即去掉小数点左侧的 1,并用 0 在右侧补齐。

  而这里的指数为 3,所以指数段 为 3 + 127 = 130 = (1000 0010)2。又因为该数为正数,因此得到的最终结果为:

(0) (1000 0010) (0011 0100 0000 0000 0000 000)

对应的十六进制结果为 0x 411A 0000。

3.5 格式化值与非格式化值
(1)格式化值

  当指数段 E 既不全为0,也不全为1,即在 (0, 2e - 2 ]之间(单精度浮点格式下为(0, 28 - 2 ],即(0, 256 ])时, 该浮点数称为格式化值。

  "格式化" 是指用唯一确定的浮点形式去表示一个值。正是由于这种表示下的尾数有一位隐含的二进制有效数字,为了与二进制科学计数法的尾数 (Mantissa) 相区别,IEEE 754 称之为有效数 (significant)。

  格式化情况下,指数的实际值 e = E - bias, bias = 2k-1 - 1,有效数字的实际值 m = 1 + M。

(2)非格式化值

  当指数段 E 全为 0 时,该浮点数称为非格式化值。

  在非格式化情况下,指数的实际值 e = 1 - bias,有效数字的实际值 m = M。也就是说,有效数字不再隐含开头的 1。

① 非格式化值表示数值0。因为格式化值必须得使有效数字 M 在范围 1 ≤ M < 2,因此格式化值不能表示 0。在给格式化情况下(即指数段 E 全为 0),把符号位 S 置 1,有效数字 M 置 0,可以得到 -0.0;同理,把 S、M均置 0,则得到 +0.0。因此,根据该浮点格式来看,值 +0.0 和 -0.0 是不同的。

一般是某个数字相当接近于零时才会使用非格式化形式来表示。这些非常接近于零的数提供了一种属性,成为逐渐下溢出。其中,可能的数值分布均匀地接近于零。

(3)特殊数值

  NaN:当指数段 E 全为 1,有效数字 M 非零时,结果值就被称为 "NaN"。一般情况下,我们将 0 / 0 或 √(-1) 视为导致计算终止的不可恢复错误,但是,一些示例表明在这样的情况下继续进行计算是有意义的。这时候就可以通过引入特殊值 NaN,并指定诸如 0 / 0 或 √(-1) 之类的表达式计算来生成 NaN 而不是停止计算,从而避免问题。下表列出了一些可以导致 NaN 的情况:

操作 产生 NaN 的表达式
+ ∞ + (-∞)
× 0 × ∞
% x % ∞, ∞ / y
/ 0 / 0, ∞ / ∞
√x (x < 0 时)

  无穷:当指数段 E 全为 1,有效数字 M 全为 0 时,得到的值表示无穷。符号位 S = 0 时是 +∞,S = 1 时是 -∞。

  无穷用于表达计算中产生的上溢问题。比如两个极大的数相乘时,尽管两个操作数本身可以保存为浮点数,但其结果可能大到无法保存为浮点数,必须进行舍入操作。根据 IEEE 标准,此时不能将结果舍入为可以保存的最大浮点数(因为这个数可能与实际的结果相差太远而毫无意义),而应将其舍入为无穷。对于结果为负数的情况也是如此。

  IEEE 754 标准规定:非规约形式的浮点数的指数偏移值比规约形式的浮点数的指数偏移值小1。例如,当指数的实际值是 -126 时,规约形式的单精度浮点数的指数域编码值为 -126 + 127 = 1,而非规约的单精度浮点数的指数域编码值为0。

  可以明确地说,所有的非规约浮点数比规约浮点数更接近 0 ;规约浮点数的有效数字大于等于 1 且 小于 2,而非规约浮点数的有效数字 小于 1 且 大于 0。IEEE 754 标准采用非规约浮点数,正是用来解决绝对值意义下最小规格数与零的距离。

3.6 舍入误差

  由于计算机的字长有限,因此在进行数值计算的过程中,对计算得到的中间结果要使用相关的舍入规则来取近似值,而这也就导致了运算得到的近似值与实际值的差异,即舍入误差。

  对于浮点数的舍入问题,IEEE 浮点格式定义了 4 种不同的舍入方式,如下表所示。其中,默认的舍入方式是向偶数舍入(将数字向上或向下舍入,使得结果的最低有效数字是偶数),而其他三种可用于计算上界和下界。

名称 描述
向偶数舍入 向最接近且可以保存的值进行舍入
向 0 舍入 向 0 的方向舍入
向上舍入 向 +∞ 方向舍入
向下舍入 向 -∞ 方向舍入

舍入规则总结:对于一个 1. mmm…mmddd…dd 形式的浮点数(m 表示有效位,或保留位,d 表示舍去位),舍入规则为:

(1)ddd…dd < 10…0,向下舍入;

(2)ddd…dd > 10…0,向上舍入;

(1)ddd…dd = 10…0,向偶数舍入:

  ① mmm…mm = xxx…0(最低有效位是 0),则向下舍入;

  ② mmm…mm = xxx…1(最低有效位是 1),则向上舍入;

参考

  • IEEE 754浮点数标准详解
  • 程序员必知之浮点数运算原理详解
  • 深入探讨浮点数舍入问题
  • 解读IEEE标准754:浮点数的表示
  • IEEE 754 浮点数的表示精度探讨
  • IEEE 754 百度百科

IEEE 754 浮点数相关推荐

  1. IEEE 754浮点数标准详解

    转载于:http://c.biancheng.net/view/314.html 在计算机系统的发展过程中,业界曾经提出过许多种实数的表达方法,比较典型的有相对于浮点数(Floating Point ...

  2. IEEE 754 浮点数的详细分析

    前言 从网上看到不少程序员对浮点数精度问题有很多疑问,在论坛上发贴询问,很多热心人给予了解答,但我发现一些解答中有些许小的错误和认识不当之处.我曾经做过数值算法程序,虽然基本可用,但是被浮点数精度问题 ...

  3. IEEE 754浮点数工业标准

    文章目录 浮点数概述 浮点数的格式 IEEE 754标准规定的浮点数的格式 IEEE 754偏移量与指数范围问题 IEEE 754中浮点数值的三种情况: 1. 规格化的浮点数的值 2. 非规格化的值 ...

  4. IEEE 754浮点数简介与C代码实现

    目录 构成 相关名称 历史 IEEE浮点数的表示形式 分类 标准浮点格式 大小端模式 代码实现 构成 浮点数表达法采用了科学计数法 来表达实数,记住一点即可:a至少为1即可: 一个有效数字.一个基数( ...

  5. 单精度浮点数计算机存储的理解(IEEE 754)

    浮点数剖析 以下是该标准对浮点数格式的描述. [编辑]本文表示比特的约定 把W个比特(bit)的数据,从内存地址低端到高端,以0到W−1编码.通常将内存地址低端的比特写在最右边,称作最低有效位(lea ...

  6. Java入门之7:Java中的float和double类型的浮点数是怎么按照IEEE 754标准存储的?

    前言: 这篇博文,我写了好几天--,里面涉及的基础概念比较多,内容比较多,举例也比较多,想搞清楚明白就难免 我自己都会觉得啰嗦,我整理了目录出来,看完需要一点时间,可以自行根据需要.感兴趣的 选择阅读 ...

  7. 【编程基础】浮点数在计算机中的存储 —— IEEE 754标准

    寻求更好的阅读体验,请移步 :浮点数在计算机中的存储 -[Mculover666的个人博客]. 用于存储小数的数据类型是有单精度浮点型(float)和双精度浮点型(double),那么,浮点数在计算机 ...

  8. IEEE 754规格化浮点数所能表示的最大值和最小值

    刚开始自己不明白最大绝对值 2- 是怎么来的,记录下 IEEE 754标准 IEEE 754标准浮点数格式: 阶码用移码表示 移码=阶码真值+偏置值 阶码真值=移码-偏置值 偏置值的公式为:2n−1− ...

  9. IEEE 754标准--维基百科

    IEEE二进制浮点数算术标准(IEEE 754) 是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用.这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denorm ...

最新文章

  1. Spring集成任务调度功能
  2. 科技互联网公司越来越重视数学了,贾扬清等大牛如是说!
  3. 如何实施好基于MOSS的企业搜索项目(上)
  4. 牛顿-拉夫逊法进行潮流计算matlab源程序
  5. 在 WebStorm 中误添加自定义的 HTML 属性,如何删除
  6. NOIP模拟测试10「大佬·辣鸡·模板」
  7. STL---vector的内存分配策略
  8. osgi java web_基于 OSGi 和 Spring 开发 Web 应用
  9. flask页面中Head标签内容为空问题
  10. 抖音记事本代码html,抖音使用教程 抖音表白代码使用方法介绍
  11. vue-aliplayer 阿里云播放器适配 vue [新]
  12. es服务器的cpu压力过大的调试
  13. 护眼html颜色,在电脑中设置护眼颜色、更换网页背景色、一键护眼
  14. oracle经纬度换算成xy坐标,经纬度换算成xy坐标(经纬度转换xy坐标算法)
  15. 电脑使用者必备的文本编辑器,哪款适合你?
  16. 按键精灵 - 安卓版 - 罗盘 - 八向方位模拟 - 自动寻路
  17. 用禅道编写测试用例(详细)
  18. android app wifi密码,无广告查看wifi密码的软件-WiFi密码查看清爽版app下载V999安卓版-西西软件下载...
  19. 多项logistic回归系数解释_深入解读Logistic回归结果(一):回归系数,OR
  20. python 数列筛选_对numpy中的数组条件筛选功能详解

热门文章

  1. 【自然语言处理】韩语基础与入门(1)
  2. 模拟扑克牌的洗牌发牌
  3. 从myspace数据库看分布式系统数据结构变迁
  4. HTML、css基础知识
  5. ACL and SCO
  6. hdu 2066 一个人的旅行 (多源最短路 )
  7. web前端三大主流框架是什么?
  8. 苹果A16的遮羞布被撕下了,性能提升幅度有限,被嘲讽为挤牙膏
  9. OpenStack的产品化历程
  10. matlab 求其骨架,数字图像处理图像的骨架生成和提取(Matlab)三种方法