浮点数剖析

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个比特的无符号整数来表示所有的指数取值,这使得两个浮点数的指数大小的比较更为容易。

规约形式的浮点数[编辑]

如果浮点数中指数部分的编码值在exponent 之间,且尾数部分最高有效位(即整数字)是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)将大于相邻的小浮点数之间的距离。例如单精度浮点数的绝对值最小的规约浮点数是, 它与绝对值次小的规约浮点数之间的距离为。如果不采用渐进式下溢出,那么绝对值最小的规约浮点数与0的距离是相邻的小浮点数之间距离的倍!可以说是非常突然的下溢出到0。这种情况的一种糟糕后果是:两个不等的小浮点数X与Y相减,结果将是0. 训练有素的数值分析人员可能会适应这种限制情况,但对于普通的程序员就很容易陷入错误了。采用了渐进式下溢出后将不会出现这种情况。例如对于单精度浮点数,指数部分实际最小值是(-126),对应的尾数部分从一直到,,相邻两小浮点数之间的距离(gap)都是;而与0最近的浮点数(即最小的非规约数)也是

特殊值[编辑]

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

1 如果 指数 是0 并且尾数的 小数部分 是0,这个数±0(和符号位相关)

2 如果 指数 =  并且尾数的 小数部分 是0,这个数是 ±(同样和符号位相关)

3 如果 指数 =  并且尾数的 小数部分 非0,这个数表示为不是一个数(NaN)

以上规则,总结如下:


形式


指数


小数部分



0


0


非规约形式


0


非0


规约形式


1 到 


任意


无穷



0


NaN



非零

32位单精度[编辑]

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


1


8


23 位长


S


Exp


Fraction


31


3023
偏正值 (实际的指数大小+127)


220 位编号(从右边开始为0)

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

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


类别


正负号


实际指数


有偏移指数


指数域


尾数域


数值



0


-127


0


0000 0000


000 0000 0000 0000 0000 0000


0.0


负零


1


-127


0


0000 0000


000 0000 0000 0000 0000 0000


?0.0


1


0


0


127


0111 1111


000 0000 0000 0000 0000 0000


1.0


-1


1


0


127


0111 1111


000 0000 0000 0000 0000 0000


?1.0


最小的非规约数


*


-126


0


0000 0000


000 0000 0000 0000 0000 0001


±2?23 × 2?126 = ±2?149 ≈ ±1.4×10-45


中间大小的非规约数


*


-126


0


0000 0000


100 0000 0000 0000 0000 0000


±2?1 × 2?126 = ±2?127 ≈ ±5.88×10-39


最大的非规约数


*


-126


0


0000 0000


111 1111 1111 1111 1111 1111


±(1?2?23) × 2?126 ≈ ±1.18×10-38


最小的规约数


*


-126


1


0000 0001


000 0000 0000 0000 0000 0000


±2?126 ≈ ±1.18×10-38


最大的规约数


*


127


254


1111 1110


111 1111 1111 1111 1111 1111


±(2?2?23) × 2127 ≈ ±3.4×1038


正无穷


0


128


255


1111 1111


000 0000 0000 0000 0000 0000


+∞


负无穷


1


128


255


1111 1111


000 0000 0000 0000 0000 0000


?∞


NaN


*


128


255


1111 1111


non zero


NaN


* 符号位可以为0或1 .

64位双精度[编辑]

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


1


11


52 位长


S


Exp


Fraction


63


6252
偏正值 (实际的指数大小+1023)


510 位编号(从右边开始为0)

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

浮点数的比较[编辑]

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

浮点数的舍入[编辑]

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

· 舍入到最接近:会将结果舍入为最接近且可以表示的值。这是缺省的近似方法。

· 朝+∞方向舍入:会将结果朝正无限大的方向舍入。

· 朝-∞方向舍入: 会将结果朝负无限大的方向舍入。

· 朝0方向舍入: 会将结果朝0的方向舍入。

时间: 2024-11-25 10:53:53

浮点数剖析的相关文章

java浮点数剖析

定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数.计算机系统采纳了所谓的浮点数表达方式.这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa也叫有效数字 ),一个基数(Base),一个指数(Exponent)以及 一个表示正负的符号来表达实数.浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数. 当一个浮点数的尾数为0,不论其阶码为何值,该浮点数的值都为0.当阶码的值为它能表示的最

java解惑之常常忘记的事

java解惑之常常忘记的事 2012-10-17 18:38:57|  分类: JAVA |  标签:基础知识  软件开发  |举报|字号 订阅 针对刚接触java的菜鸟来说,java基础知识都是我们必须认真学习的,但是在工作过几年时间的老鸟来说,有时候也会对java的基础知识产生疑问,对于这种不确定,并且很容易混淆的知识点,java解惑已经为大家进行了很好的总结,现在借用一个作者的总结,进行一下罗列,希望能对你有所帮助. 1. 奇偶判断 不要使用 i % 2 == 1 来判断是否是奇数,因为i

Float之谜

先来看几个例子: public class Thirtyfirst1{ public static void main(String[] args){ int i = 2000000000; int count = 0; for(float f = i; f < i + 50 ; f ++){ count++; } System.out.println(count); } } 会输出多少? public class Thirtyfirst1{ public static void main(St

C语言进阶剖析第三课--浮点数的秘密

浮点数在内存中的存储方式:符号数,指数,尾数 float与double类型的数据在计算机内部的表示法是相同的,但由于所占存储空间的不同:其分别能够表示的数值范围和精度不同 浮点数转换方法 1.将浮点数转换成二进制 2.用科学计数法表示二进制浮点数 3.计算指数偏移后的值 注意:计算指数时需要加上偏移量,而偏移量的值与类型有关.

剖析金额不能用浮点数表示的原因

??近期支援双十一红包项目.参与到了一个涉及到钱的项目,开发自然十分的谨慎.先抛出我有问题的代码,作用是把以分为单位的金额转成以元为单位的字符串. long adjustFee; String.valueOf(adjustFee / 100.0); ??很自信的以为这行代码简洁明了的完成了使命.@壹双 同学review了我的代码后,指出这段代码会造成精度丢失的问题.先演示一个demo,构造一个浮点数丢失精度的场景. @Test public void addTest() { long l = L

深度剖析数据在内存中的存储2——浮点数数在内存中的存储

根据国际标准IEEE:任意一个二进制浮点数V可以表示为下面形式:(-1)^SM2^E:(-1)^S表示符号位,当S为0,V为正数:当S为1,V为负数.由其物理结构决定了,浮点数为有符号数.M为有效数字,大于等于1,小于2.2^E表示指数位.eg:5=>0101=>(-1)^01.012^2. S=0,M=1.01,E=2规定:对于32位的浮点数(单精度浮点数存储),最高1位是符号位(S),接着的8位为指数位(E),剩下的23位是有效数字位(M),不满23位后面补0.对于64位的浮点数(双精度浮

深入剖析Java中的装箱和拆箱

阅读目录 一.什么是装箱?什么是拆箱?二.装箱和拆箱是如何实现的三.面试中相关的问题 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱.拆箱相关的问题. 回到顶部 一.什么是装箱?什么是拆箱? 我们知道 Java为每种基本数据类型都提供了对应的包装器类型,至于为什么会为每种基本数据类型提供包装器类型在此不进行阐述,有兴趣的朋友可以查阅相关资料.在Java SE5之前,如果要生成

深入剖析Java中的装箱和拆箱(转)

自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱.拆箱相关的问题. 以下是本文的目录大纲: 一.什么是装箱?什么是拆箱? 二.装箱和拆箱是如何实现的 三.面试中相关的问题 一.什么是装箱?什么是拆箱? 在前面的文章中提到,Java为每种基本数据类型都提供了对应的包装器类型,至于为什么会为每种基本数据类型提供包装器类型在此不进行阐述,有兴趣的朋友可以查阅相关资料.在Java SE

深入剖析C/C++函数的参数传递机制

2014-07-29 20:16 深入剖析C/C++函数的参数传递机制 C语言的函数入口参数,可以使用值传递和指针传递方式,C++又多了引用(reference)传递方式.引用传递方式在使用上类似于值传递,而其传递的性质又象是指针传递,这是C++初学者经常感到困惑的.为深入介绍这三种参数传递方式,我们先把话题扯远些: 1. C/C++函数调用机制及值传递: 在结构化程序设计方法中,先辈们告诉我们,采用“自顶向下,逐步细化”的方法将一个现实的复杂问题分成多个简单的问题来解决.而细化到了最底层,就是