Floating point 什么时候非规范化真正有用?

Floating point 什么时候非规范化真正有用?,floating-point,ieee-754,Floating Point,Ieee 754,每当我搜索术语“非规范数”或“非规范数”时,我只找到如何检测它们并将它们四舍五入为零的方法。显然,没有人真正喜欢它们,因为与它们打交道会导致性能下降 然而,它们在任何地方都得到了实施。为什么?如果是为了精度,我会说你需要一个更大的浮点,或者改变你的操作顺序,这样你就可以避免非常小的中间值。我发现很难相信这一点点额外的精度真的值得宝贵的时钟周期 有没有什么好的理由可以解释为什么人们仍然使用非规范数?如果没有重要的理由去使用非规范数字,为什么要实现它们呢?只是为了符合IEEE754?简而言之,因为逐

每当我搜索术语“非规范数”或“非规范数”时,我只找到如何检测它们并将它们四舍五入为零的方法。显然,没有人真正喜欢它们,因为与它们打交道会导致性能下降

然而,它们在任何地方都得到了实施。为什么?如果是为了精度,我会说你需要一个更大的浮点,或者改变你的操作顺序,这样你就可以避免非常小的中间值。我发现很难相信这一点点额外的精度真的值得宝贵的时钟周期


有没有什么好的理由可以解释为什么人们仍然使用非规范数?如果没有重要的理由去使用非规范数字,为什么要实现它们呢?只是为了符合IEEE754?

简而言之,因为逐渐下溢保留了一些有用的数学恒等式(例如x-y==0意味着x==y)。关于为什么逐渐下溢可能有用的一些解释:

是的,在某些情况下,由于糟糕的应用程序设计会遇到下溢,正确的操作是修复应用程序。在其他情况下,在逐渐下溢的情况下正常工作的应用程序在突然下溢的情况下会失败

此外,

  • 在许多情况下,缓慢但正确的违约被认为比快速但危险的违约更好

  • 由于默认情况是逐渐下溢,谷歌发现有人对此表示不满,并希望将其关闭。如果OTOH突然下溢是默认情况,也许相反,你会看到更多的人抱怨神秘的数字问题?数值编程已经够难的了

  • 现代硬件降低了使用低于正常数字的惩罚。见例


    • 非规范化非常有用;浮点计算中有许多有用的错误界限,如果删除非规范化,这些界限就不再成立(最重要的是
      x-y==0
      当且仅当
      x==y


      记住(a)非规范化不会对所有硬件产生惩罚,这一点也很重要;有一些系统可以快速(或非常接近)处理非规范化,(b)非规范化只会在实际遇到时减慢计算速度。如果你不使用它们,你就不会为它们付费(如果你最终使用了它们,那么没有它们,你的结果很可能是错误的——如果你只是想尽快得到一个错误的答案,你可以用
      返回0
      )来代替你的整个计算).

      看起来你在第二段末尾写了“渐进”的意思是“突然”。“x-y==0意味着x==y”请解释一下。@Tintorius:你链接的页面上绝对没有与此相矛盾的内容。更重要的是,它是浮点误差分析的一个基本定理(即,它在数学上是正确的);没有什么可以“解释”的,我应该更清楚一点。我的意思是:请解释这是一个多么有用的属性,因为在进行FP计算时,
      x==y
      x-y==0
      是一种难闻的气味。你总是需要知道你的误差范围(不要忘记错误中的错误,或者不管它叫什么),比较应该总是像
      |x-y |@Tinctorius:“代码气味”对于那些不知道自己在做什么的人来说是一个过于粗糙的准则(或者懒得仔细阅读有问题的来源)。精确的FP比较(尤其是零)在许多情况下都是适当和正确的;对于理解浮点运算的人来说,它们是绝对有用的。作为参考,这里有一个例子说明了非规范化有多糟糕:如果你想要一个完全正确的计算,请使用bignum。选择浮点的原因是为了以精度换取效率。这同样适用于选择不使用非规范化。实际上,您可以指示编译器禁用它们。