3

非正规浮点数特别:

浮点数分类与表示

ISO-Prolog 标准对如何处理这些问题有何规定?

我很清楚,evaluation_error(underflow)每当发生这些异常时引发异常处理它们的正确方法,但这会产生额外的成本——必须检查产生的每个浮点数。

但是许多处理器提供的“将非正规化为零”(FTZ)和“将非正规化视为零”(DAZ)操作模式呢?Prolog 实现可以使用这些,如果可以,它们如何正确地做到这一点?

(1) 记录这些操作模式的使用,(2) 确保非正规数被刷新到同符号的零 (FTZ),以及 (3) 确保非正规数被视为同符号的零 (DAZ) 就足够了吗?请帮忙!

4

3 回答 3

2

在第 7.1.3 节中,ISO-Prolog 标准将集合F定义为您选择的浮点格式可以表示的数字集合。这个集合可能包括也可能不包括非规范化的值,这两种选择都是允许的。

当计算结果(绝对)大于零且小于最小归一化值时,您可以选择

  • 四舍五入到 F 中可表示的值
  • 引发下溢异常

根据第 9.1.4.2 节,这个选择是实现定义的,即你必须记录它。

于 2020-09-03T22:23:08.507 回答
2

不要跳过它们。然而,来自 ISO/IEC 13211-1:1995 9.1.4.2 浮点结果函数的简短回答:

当 0 < | 时,处理器是否
选择舍入( x ) 或下溢应由实现定义。x | < fmin N

但首先,让我们称它们为次常态。过时的(至少根据LIA 1:2012)概念非正规(回想起来)不是很有帮助,因为它暗示了一些异常的、破坏性的特性。不:它们并不像您建议的那样特别。要看到这一点,请考虑实数的数轴。可以精确表示的数字被标记并且在接近零时(从两侧)越来越接近。次正常是最接近于零的那些。它们与零之间的距离与最小法线数之间的距离相同。那是他们的异常(或者可以说是异常)。如果你现在删除那些次正常,你会得到一个巨大的差距,导致更多的数值异常。就像你在尺子上刮掉零旁边的标记,然后用这把破尺子测量1. 因此,在没有次常态的情况下,剩余的数字并不像人们想象的那样正常,而是不正常的,容易出现更多错误。

如果您不喜欢就我建议的主题阅读 Kahan,我可以向您推荐 Gustafson 的The end of error,它比我更好地解释了次常态。

在 13211-1 中,可以排除次规范,但这只是为了与非常 RISCy 的过时架构兼容。

正式的一致性就这么多。从长远来看,一些 Unum 风格、CLP(BNR) 式、Prolog IV 式的方法可能很有前途。


 1) 也就是说,如果您四舍五入为零。如果您生成异常/延续值,只要不发生此类异常,就会保持更好的数值属性。

于 2020-08-11T11:59:47.587 回答
1

这是一个小测试用例,用于查看您的 Prolog 系统是否可以作为算术结果返回次正规(没有清零,~FTZ):

/* SWI-Prolog */
?- X is 2.2250738585072011e-308 - 2.2250738585072012e-308.
X = -5.0e-324.
/* Jekejeke Prolog */
?- X is 2.2250738585072011e-308 - 2.2250738585072012e-308.
X = -4.9E-324

这是 API 中的新增功能,在 Prolog 系统中不一样,显示了次规范的参数传递(没有非规范为零,~DAZ):

/* SWI-Prolog */
?- X is 2.2250738585072011e-308 - 2.2250738585072012e-308, 
float_parts(X,M,B,E).
X = -5.0e-324,
M = -0.5,
B = 2,
E = -1073.
/* Jekejeke Prolog */
?- X is 2.2250738585072011e-308 - 2.2250738585072012e-308, 
sys_float_mantissa(X,M), sys_float_exponent(X,E), sys_float_radix(X,R).
X = -4.9E-324,
M = -1,
E = -1074,
R = 2

结果来自 MacBook Air 2019。

于 2021-04-03T22:10:44.530 回答