IEEE754分度精度

时间:2015-01-09 10:15:23

标签: floating-point floating-accuracy

从IEEE754开始,我读了

  

[...]每次操作都应该像第一次生产中间体一样进行   结果正确到无限精度和无界范围,然后四舍五入   结果[...]。

我的理解是,当将1.0108552519184509e+760x4FB6593CEBC97CC5)除以4.1777521369084075e+1470x5E94E917A9CC65DC)时,理论中间部分是 (二进制)

1.0001000110011011000100110000110101001010110111101110100000000000001...

并且应该四舍五入到(舍入模式“最近”)

1.0001000110011011000100110000110101001010110111101111

产生2.41961518728705e-720x311119B130D4ADEF)的商。

这里的一个SW产生2.4196151872870495e-720x311119B130D4ADEE),这似乎表明它只计算中间部分到某个位置,例如

1.000100011001101100010011000011010100101011011110111010000000000

然后回合。

这符合IEEE754吗?这是一种常见的方法吗?

2 个答案:

答案 0 :(得分:3)

在要求澄清之后,问题是关于IEEE 754,与编程语言无关。在这种情况下,在“舍入到最近”中获得正在考虑的除法的结果2.4196151872870495e-72纯粹而且完全不正确。根据问题中的定义,正确的结果是2.41961518728705e-72

  

[...]每个操作都应该执行,好像它首先产生一个正确的无限精度和无限范围的中间结果,然后舍入结果[...]。

在实践中发生的事情是,大多数编程语言实现(通常是规范)并未强调严格遵守IEEE 754语义的浮点运算。即使使用IEEE 754双精度表示来存储浮点值,操作最终也可以实现为:

  • 如果参数不是具有64位有效数字的80位浮点值,则转换从双精度到此格式。这不会失去精确度,本身也不会成为问题

  • 从80位操作数计算80位结果,因为在使用8087指令集进行计算时,这很容易,而且不需要额外的工作

  • 在此之后或之后,转换(换句话说,舍入)的80位值及其64位有效数字为具有53位有效数字的精度值。

在某些情况下,最后一步不会立即发生,而是随着编译器的突发奇想而发生。这特别令人讨厌,因为它使代码不确定。添加不应影响计算的单独调试代码确实会通过更改80位寄存器的可用性并导致其中一些寄存器溢出并舍入为双精度来改变它们。

即使对于每个中间结果立即发生双精度存储,仍然存在这样的问题:对于64位的有效位数,已经计算并正确舍入结果,然后再次舍入为53位。在某些情况下,数学结果接近两个双精度值之间的中点,并将其四舍五入为64位有效数据并将其拖动到精确的中间值。如果将具有64位有效位数的结果舍入为53位,则最终结果与IEEE 754规则的直接应用产生的值不同。只有当数学结果非常接近两个双精度数之间的中点时才会发生这种情况,因此这两个答案都是几乎同样准确的答案,但其中一个是IEEE 754标准所说的而不是另一个。

文章The pitfalls of verifying floating-point computations更进一步 读数。

注意:

如Patricia在她的回答中所提到的那样,IEEE 754指定+, - ,*,/和√应该计算好像数学结果(有时是无限数字)已被计算然后舍入的原因是算法存在以获得该结果而不计算整个数学结果。如果没有算法可以廉价地获得这种“正确舍入”的结果,例如对于三角函数,标准并没有强制要求它。

由于您在页面上找到了一个解决方案,解释了如何将387 FPU配置为直接在53位有效数字处进行舍入,我应该指出,即使在此配置之后,双舍入问题仍然存在,尽管很少见。实际上,虽然FPU的有效位数可以限制为53位,但没有相同的方法来限制指数。即使在53位有效数模式下,在387上计算时,产生次正规结果的双精度运算也往往是双舍入的。这导致我问这个question about how Java implementations implement multiplication on the 387

答案 1 :(得分:1)

有些语言允许额外的精确度,这似乎是这里发生的事情。我使用Java的BigDecimal将输入的精确表示划分为1000个小数位。结果以" 2.419615187287049816675514541262468407091280398183303735778952998096290304758722566"开始,稍微接近较低值。

在给定的计算中是否允许额外的精度是语言规范的问题。

通常,浮点运算使用保护数字来获得相同的结果,就好像计算已经精确完成然后舍入一样。要进行最接近的正常舍入,系统需要知道将保留的位之外的一位,以及是否有任何较低有效位为1的指示。