2012-08-06 40 views

回答

4

您的问题的答案是“否”。浮点数是(通常是*)用归一化尾数和指数表示。乘法和除法首先在规范化的尾数上运行,然后在指数上运行。

加法和减法当然是另一回事。像你的例子一样的操作:

567.56 + 345.54 or .00097854 - .00021297 

工作正常。但是运行的数量级别不一样,如

567.56 + .00097854 or 345.54 - .00021297 

可能会失去一些低阶精度。

+0

1994年,第一个奔腾出现了,并且在逻辑分区方面出现了缺陷。 http://en.wikipedia.org/wiki/Denormal_number这是玩笑。这是1994年的圣诞节,Andy Grove(英特尔的老板)已经度过了不错的一年。他走进一家酒吧,点了一杯27岁的单麦芽苏格兰威士忌来庆祝。调酒师说,“那将是20美元,先生。”格罗夫在酒吧上放了二十美元的钞票,看了一会儿,然后说“保持变化”。 – 2012-08-06 22:07:30

+0

在音频和其他信号处理应用中也会遇到非规格化数字,特别是在使用无限脉冲响应滤波器的情况下(如回波效应)。回波随着时间的推移而减小,当输入保持为零时,回波最终达到非规格化的范围。 – 2012-08-08 16:57:14

0

不需要。在某种意义上,无论数字的数量级(指数部分)是多少,都有相同的有效位数。

+0

这不完全正确。对于0x1p-126(浮点型)或0x1p-1022(双精度型)下的数字,精度会有所下降。 – 2012-08-08 16:55:44

+0

@EricPostpischil你说得对,我忽略了那里的低于正常水平的数字。然而,原始海报中的数字并不接近于低于正常水平,我想给出一个“简单”的答案。 – 2012-08-08 17:02:36

1

对于IEEE 754二进制浮点数(最常见的),浮点值必须在有效数相同的比特数的在大部分指数范围的。但是,有一部分范围的有效位的有效位数较少。由舍入引起的相对误差确实取决于有效位于其范围内的位置。

IEEE 754浮点数用符号(+1或-1,编码为0或1)表示,指数(对于双精度,-1022至1023,编码为指数加1023,so 1到2046)以及一个有效数字(对于双精度,通常从1到不足2的分数,用53位表示,但用52位编码,因为第一位隐含地为1)。例如,数字6.5用位0(符号+1),10000000001(指数2)和1010000000000000000000000000000000000000000000000000(二进制小数1.1010,十六进制1.a,十进制1.3125)编码。我们可以将它写成十六进制浮点数0x1.ap2(十六进制小数1.a乘以2的十进制数2)。用十六进制浮点写入可以让人类很容易地看到浮点表示。

对于指数,编码值0和2047是特殊的。当编码为0时,指数与编码为1(-1022)时的指数相同,但分数的隐含位为0而不是1.当编码为2047时,浮点对象表示无穷大(if有效位全部为零)或NaN(否则)。

当编码指数为0且有效位全部为零时,数字代表零(以符号区分+0和-0)。如果有效位不全为零,则说该数字是非规格化的。这是因为大多数数字都是通过调整指数来“归一化”的,以便分数介于1(包含)和2(不包含)之间。对于非规格化的数字,分数小于1;它以“0”而不是“1”开始。

当浮点运算的结果是一个非规格化数时,它在有效数中有效地具有较少的位。因此,当数字低于0x1p-1022(2 -1022)时,有效精度下降。

当数字是在正常范围内(未下溢到非正规数和不溢出到无穷大),则存在与不同的指数数字的有效数没有差异,所以:

  • (2A + 2b)的/ 2与a + b具有完全相同的结果。
  • (2a-2b)/ 2与a-b具有完全相同的结果。
  • (2ab)/ 2与ab具有完全相同的结果。

但是请注意,相对误差可能会改变。当执行浮点运算时,精确的数学结果必须舍入到可表示的值。这个四舍五入只能以有效数表示的单位发生。对于给定的指数,有效位中的位具有固定值。所以有效位中的最后一位代表了一定的值。该值是有效数值接近1的较大部分而不是有效数字接近2.

对于双精度结果,最小精度(ULP)的单位是1的一部分在有效数字中最重要的一点。当使用圆到最近的模式(最常见的默认模式)时,最大误差最多只有一半,因为如果一个方向上的可表示数量超过ULP的一半,那么另一个方向上的数量就会减少远远超过一半ULP。接近的数字通过适当的浮点运算返回。

因此,与接近1的有效数的结果的最大相对误差为略微超过2 -53,但在与邻近2有效数的结果的最大相对误差在2 -54略。

1

为了完整起见,我不得不同意了一下,说,它可能以某种重要...
事实上,如果执行56756.0/34554.0,那么你会得到最接近的可表示浮点数到精确的数学结果,用单个浮点四舍五入“错误”。
这是因为56756.0和34554.0完全可以在浮点(单精度或双精度IEEE 754)中表示,并且由于根据IEEE 754标准,操作会执行精确的舍入操作(默认模式为最近)。

如果你写567.56/345.54,那么这两个数字都不是以浮点数2为基数完全表示的,所以这个操作的结果是累积了3个浮点舍入“错误”。

让我们比较结果佳乐Smalltalk中的双精度(浮点数),转换(在分子和分母分数任意整数长度),以精确的算法:

((56756.0/34554.0) asFraction - (56756/34554)) asFloat. 
-> -7.932275867322412e-17 

到目前为止,一切都很好,幅度误差小于或等于半ULP,由IEEE 754承诺:

(56756/34554) asFloat ulp/2 
-> 1.1102230246251565e-16 

随着累积舍入误差,可能会出现较大误差(但从来没有一个更小的):

((567.56/345.54) asFraction - (56756/34554)) asFloat 
-> -3.0136736359825544e-16 

((0.00056756/0.00034554) asFraction - (56756/34554)) asFloat 
-> 3.647664511768385e-16 

上面的例子很难概括,我完全同意其他答案:一般来说,你应该只关心相对精度。
...除非也许如果你想实现一些功能与非常严格的容忍关于四舍五入错误...