定点数与浮点数区别
最近做HDR 时,经常要用NV 提供的16 位纹理,它的说明书16 位能达到24 位的精度,就很
奇怪,一直搞不懂浮点数的精度怎么算的,
今天认真看了一下IEEE float point 的
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
,终于明白是什么了
1. 什么是浮点数
在计算机系统的发展过程中,曾经提出过多种方法
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
达实数。典型的比如相对于浮点数的定
点数(Fixed Point Number)。在这种表达方式中,小数点固定的位于实数所有数字中间的某
个位置。货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位
精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位
数值来表达相应的数值。SQL 中的 NUMBER 数据类型就是利用定点数来定义的。还有一种提
议的表达方式为有理数表达方式,即用两个整数的比值来表达实数。
定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和
小数部分,不利于同时表达特别大的数或者特别小的数。最终,绝大多数现代的计算机系统
采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数
(Mantissa ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实
数。比如 123.45 用十进制科学计数法可以表达为 1.2345 × 102 ,其中 1.2345 为尾数,
10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活乇泶锔 范围的实数。
提示: 尾数有时也称为有效数字(Significand)。尾数实际上是有效数字的非正式说法。
同样的数值可以有多种浮点数表达方式,比如上面例子中的 123.45 可以表达为 12.345 ×
101,0.12345 × 103 或者 1.2345 × 102。因为这种多样性,有必要对其加以规范化以达
到统一表达的目标。规范的(Normalized)浮点数表达方式具有如下形式:
?d.dd...d × β e , (0 ? d i 和 >= 在任一操作
数为 NaN 时均返回 false。等于操作符 == 在任一操作数为 NaN 时均返回 false,即使是
两个具有相同位模式的 NaN 也一样。而操作符 != 则当任一操作数为 NaN 时返回 true。这
个规则的一个有趣的结果是 x!=x 当 x 为 NaN 时竟然为真。
可以产生 NaN 的操作如下所示:
此外,任何有 NaN 作为操作数的操作也将产生 NaN。用特殊的 NaN 来表达上述运算错误的
意义在于避免了因这些错误而导致运算的不必要的终止。比如,如果一个被循环调用的浮点
运算方法,可能由于输入的参数问题而导致发生这些错螅琋aN 使得 即使某次循环发生了这
样的错误,也可以简单地继续执行循环以进行那些没有错误的运算。你可能想到,既然 Java
有异常处理机制,也许可以通过捕获并忽略异常达到相同的效果。但是,要知道,IEEE 标准
不是仅仅为 Java 而制定的,各种语言处理异常的机制不尽相同,这将使得代码的迁移变得
更加困难。何况,不是所有语言都有类似的异常或者信号(Signal)处理机制。
注 意 : Java 中 , 不 同 于 浮 点 数 的 处 理 , 整 数 的 0 除 以 0 将 抛 出
java.lang.ArithmeticException 异常。
4.2. 无穷
和 NaN 一样,特殊值无穷(Infinity)的指数部分同样为 emax + 1 = 128,不过无穷的尾
数域必须为零。无穷用于表达计算中产生的上溢(Overflow)问题。比如两个极大的数相乘
时,尽管两个操作数本身可以用保存为浮点数,但其结果可能大到无法保存为浮点数,而必
须进行舍入。根据 IEEE 标准,此时不是将结果舍入为可以保存的最大的浮点数(因为这个
数可能离实际的结果相差太远而毫无意义),而是将其舍入为无穷。对于负数结果也是如此,
只不过此时舍入为负无穷,也就是说符号域为 1 的无穷。有了 NaN 的经验我们不难理解,
特殊值无穷使得计算中发生的上溢错误不必以终止运算为结果。
无穷和除 NaN 以外的其它浮点数一样是有序的,从小到大依次为负无穷,负的有穷非零值,
正负零(随后介绍),正的有穷非零值以及正无穷。除 NaN 以外的任何非零值除以零,结果
都将是无穷,而符号则由作为除数的零的符号决定。
回顾我们对 NaN 的介绍,当零除以零时得到的结果不是无穷而是 NaN 。原因不难理解,当
除数和被除数都逼近于零时,其商可能为任何值,所以 IEEE 标准决定此时用 NaN 作为商比
较合适。
4.3. 有符号的零
因为 IEEE 标准的浮点数格式中,小数点左侧的 1 是隐藏的,而零显然需要尾数必须是零。
所以,零也就无法直接用这种格式表达而只能特殊处理。
实际上,零保存为尾数域为全为 0,指数域为 emin - 1 = -127,也就是说指数域也全为 0。
考虑到符号域的作用,所以存在着两个零,即 +0 和 -0。不同于正负无穷之间是有序的,IEEE
标准规定正负零是相等的。
零有正负之分,的确非常容易让人困惑。这一点是基于数值分析的多种考虑,经利弊权衡后
形成的结果。有符号的零可以避免运算中,特别是涉及无穷的运算中,符号信息的丢失。举
例而言,如果零无符号,则等式 1/(1/x) = x 当x = ?? 时不再成立。原因是如果零无符
号,1 和正负无穷的比值为同一个零,然后 1 与 0 的比值为正无穷,符号没有了。解决这
个问题,除非无穷也没有符号。但是无穷的符号表达了上溢发生在数轴的哪一侧,这个信息
显然是不能不要的。零有符号也造成了其它问题,比如当 x=y 时,等式1/x = 1/y 在 x 和
y 分别为 +0 和 -0 时,两端分别为正无穷和负无穷而不再成立。当然,解决这个问题的另
一个思路是和无穷一样,规定零也是有序的。但是,如果零是有序的,则即使 if (x==0) 这
样简单的判断也由于 x 可能是 ?0 而变得不确定了。两害取其轻者,零还是无序
的好。
4.4. 非规范化数
我们来考察浮点数的一个特殊情况。选择两个绝对值极小的浮点数,以单精度的二进制浮点
数为例,比如 1.001 × 2-125 和 1.0001 × 2-125 这两个数(分鸲杂τ谑频?
2.6448623 × 10-38 和 2.4979255 × 10-38)。显然,他们都是普通的浮点数(指数为 -125,
大于允许的最小值 -126 ;尾数更没问题),按照 IEEE 754 可以分别保存为
00000001000100000000000000000000(0x1100000)和
00000001000010000000000000000000
(0x1080000)。
现在我们看看这两个浮点数的差值。不难得出,该差值为 0.0001 × 2-125,表达为规范浮
点数则为 1.0 × 2-129。问题在于其指数大于允许的最小指数值,所以无法保存为规范浮点
数。最终,只能近似为零(Flush to Zero)。这中特殊情况意味着下面本来十分可靠的代码
也可能出现问题:
if (x != y) {
z = 1 / (x -y);
}正如我们精心选择的两个浮点数展现的问题一样,即使 x 不等于 y,x 和 y 的差值仍然可
能绝对值过小,而近似为零,导致除以 0 的情况发生。
为了解决此类问题,IEEE 标准中引入了非规范(Denormalized)浮点数。规定当浮点数的指
数为允许的最小指数值,即 emin 时,尾数不必是规范化的。比如上面例子中的差值可以表
达为非规范的浮点数 0.001 × 2-126,其中指数 -126 等于 emin。注意,这里规定的是"
不必",这也就意味着"可以"。当浮点数实际的指数为 emin,且指数域也为 emin 时,该浮
点数仍是规范的,也就是说,保存时隐含着一个隐藏的尾数位。为了保存非规范浮点数,IEEE
标准采用了类似处理特殊值零时所采用的办法,即用特殊的指数域值 emin - 1 加以标记,
当 然 , 此 时 的 尾 数 域 不 能 为 零 。 这 样 , 例 子 中 的 差 值 可 以 保 存 为
00000000000100000000000000000000(0x100000),没有隐含的尾数位。
有了非规范浮点数,去掉了隐含的尾数位的制约,可以保存绝对值更小的浮点数。
而且,也
由于不再受到隐含尾数域的制约,上述关于极小差值的问题也不存在了,因为所
有可以保存
的浮点数之间的差值同样可以保存。
A 16-bit floating-point number has a 1-bit sign (S), a 5-bit
exponent (E), and a 10-bit mantissa (M). The value of a 16-bit
floating-point number is determined by the following:
(-1)^S * 0.0, if E == 0 and M == 0,
(-1)^S * 2^-14 * (M / 2^10), if E == 0 and M != 0,
(-1)^S * 2^(E-15) * (1 + M/2^10), if 0 < E < 31,
(-1)^S * INF, if E == 31 and M == 0, or
NaN, if E == 31 and M != 0,
where
S = floor((N mod 65536) / 32768),
E = floor((N mod 32768) / 1024), and
M = N mod 1024.
因此当E=0 时,按非规范浮点数处理得到的结果就2^-24 精度的数字