简体   繁体   English

C 浮点异常处理

[英]C floating point exception handling

The manual pages for fenv.h ( feraiseexcept and its ilk) are unusually uninformative; fenv.h的手册页( feraiseexcept及其同类)非常缺乏信息。 the examples I find online (cppreference.com and others) are very minimal.我在网上找到的示例(cppreference.com 等)非常少。

How are they supposed to be used?它们应该如何使用? In particular, does feraiseexcept(...) always return?特别是, feraiseexcept(...)总是返回吗? What should one return from a function that gets an illegal argument, like sqrt(-1) ?应该从获得非法参数的 function 返回什么,例如sqrt(-1) I assume NAN .我假设NAN

Should one get and restore the original state in a function?是否应该在 function 中获取并恢复原始 state? For example, one might compute a starting point for some iterative algorithm, if that computation turns out inaccurate is of no consequence as presumably, the iteration can converge to full precision.例如,一个人可能会为某个迭代算法计算一个起点,如果该计算结果不准确并没有任何后果,那么迭代可以收敛到全精度。

How should one use this in a program calling eg library functions?在调用例如库函数的程序中应该如何使用它?

(I'd prefer not to have to dive into random math library sources to answer the above.) (我宁愿不必深入研究随机数学库资源来回答上述问题。)

The manual pages for fenv.h ( feraisexceptionand [its] ilk) are unusually uninformative, the examples I find on line (cppreference.com and others) are very minimal. fenv.hferaisexceptionand [its] ilk )的手册页非常缺乏信息,我在网上找到的示例(cppreference.com 等)非常少。

<fenv.h> is specified by the C standard . <fenv.h>C 标准指定。 The Unix manual pages are useful only insofar as they extend the C specification. Unix 手册页仅在扩展 C 规范时才有用。 Regard cppreference.com with skepticism;对 cppreference.com 持怀疑态度; it is known to have errors.已知有错误。

How are they supposed to be used?它们应该如何使用?

Discussing all of <fenv.h> is too broad a question for Stack Overflow.讨论所有<fenv.h>对于 Stack Overflow 来说是一个过于宽泛的问题。

In particular, does feraisexception(...) always return?特别是, feraisexception(...)总是返回吗?

Per C 2018 7.6.2.3 2 and foonote 221, feraiseexcept attempts to cause floating-point exceptions as if they had been generated by arithmetic instructions.根据 C 2018 7.6.2.3 2 和 foonote 221, feraiseexcept尝试导致浮点异常,就好像它们是由算术指令生成的一样。 Thus, if it raises an exception for which a trap is enabled, it will cause a trap.因此,如果它引发一个启用了陷阱的异常,它将导致一个陷阱。

In contrast, fesetexceptflag merely sets floating-point exception flags without generating actual exceptions.相反, fesetexceptflag仅设置浮点异常标志,而不会生成实际异常。 Per 7.6.2.4 2, “… This function does not raise floating-point exceptions, but only sets the state of the flags.”根据 7.6.2.4 2,“……此 function 不会引发浮点异常,而只会设置标志的 state。”

What should one return from a function that gets an illegal argument, like sqrt(-1) ?应该从获得非法参数的 function 返回什么,例如sqrt(-1) I assume NAN .我假设NAN

This is outside the domain of <fenv.h> .这在<fenv.h>的域之外。 sqrt is specified in 7.12, covering <math.h> . sqrt在 7.12 中指定,涵盖<math.h> Per 7.12.7.5 2, a sqrt domain error occurs if the argument is less than zero.根据 7.12.7.5 2,如果参数小于零,则会发生sqrt域错误。 Per 7.12.1, 2, “… On a domain error, the function returns an implementation-defined value…” and it may also set errno and/or raise the “invalid” floating-point exception.根据 7.12.1, 2,“……在域错误中,function 返回实现定义的值……”并且它还可能设置errno和/或引发“无效”浮点异常。 Commonly, implementations will return a quiet NaN.通常,实现将返回安静的 NaN。

Should one get and restore the original state in a function?是否应该在 function 中获取并恢复原始 state?

This is up to the person who is specifying or implementing a function.这取决于指定或实施 function 的人。 Routines that provide “elementary” mathematical functions, as for the standard math library, may be required to affect the floating-point state only as called for by the ideal function being provided, concealing any internal operations.提供“基本”数学函数的例程,对于标准数学库,可能需要影响浮点 state,仅在提供的理想 function 所要求的情况下,隐藏任何内部操作。 For example, if log10(100) is implemented by using an engineered polynomial to approximate the logarithm, the evaluation of the polynomial might use arithmetic operations that have very high precision and accuracy, so high that the final result, when rounded to the final format, is exactly two.例如,如果log10(100)是通过使用工程多项式来逼近对数来实现的,那么多项式的评估可能会使用具有非常高的精度和准确度的算术运算,以至于最终结果在四舍五入到最终格式时, 正好是两个。 But the intermediate calculations might involve some operations that were inexact.但是中间计算可能涉及一些不精确的操作。 Thus, the inexact exception would be raised.因此,将引发不精确的异常。 If the routine merely evaluated the polynomial and returned the exact result, 2, it would have raised the inexact flag.如果例程仅计算多项式并返回准确的结果 2,它将引发不准确标志。 Ideally, the routine would suppress floating-point traps, save the exception flags, do its calculations, restore originally enabled traps, set the proper exception flags if any, and return the result.理想情况下,例程将抑制浮点陷阱、保存异常标志、进行计算、恢复最初启用的陷阱、设置适当的异常标志(如果有)并返回结果。 (Alternately, the routine might be implemented to use only integer arithmetic, avoiding the floating-point issues.) (或者,可以实现例程以仅使用 integer 算法,避免浮点问题。)

Outside of specialized library routines, floating-point subroutines rarely go to this extent.在专门的库例程之外,浮点子例程很少 go 到这种程度。 It is up to each application how it wants its routines to behave.取决于每个应用程序希望其例程如何运行。

For example, one might compute a starting point for some iterative algorithm, if that computation turns out inaccurate is of no consecuence as pressumably the iteration can converge to full precision.例如,一个人可能会为某个迭代算法计算一个起点,如果该计算结果不准确是不连续的,因为迭代可能会收敛到全精度。

This paragraph is unclear and may be ungrammatical.这一段不清楚,可能不合语法。 I am unable to answer it as written.我无法按书面方式回答。

How should one use this in a program calling eg library functions?在调用例如库函数的程序中应该如何使用它?

This question is unclear, possibly due to the lack of clarity of the preceding paragraph.这个问题不清楚,可能是因为前一段不够清晰。 The antecedent of “this” is unclear. “这”的来历不明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM