处理浮点异常

Tim*_*Tim 11 c c++ floating-point signals exception

我不知道如何处理C或C++中的浮点异常.从wiki中,有以下类型的浮点异常:

IEEE 754 specifies five arithmetic errors that are to be recorded in "sticky bits" (by default; note that trapping and other alternatives are optional and, if provided, non-default).  

* inexact, set if the rounded (and returned) value is different from the mathematically exact result of the operation.  
* underflow, set if the rounded value is tiny (as specified in IEEE 754) and inexact (or maybe limited to if it has denormalisation loss, as per the 1984 version of IEEE 754), returning a subnormal value (including the zeroes).  
* overflow, set if the absolute value of the rounded value is too large to be represented (an infinity or maximal finite value is returned, depending on which rounding is used).  
* divide-by-zero, set if the result is infinite given finite operands (returning an infinity, either +? or ??).  
* invalid, set if a real-valued result cannot be returned (like for sqrt(?1), or 0/0), returning a quiet NaN.
Run Code Online (Sandbox Code Playgroud)

是否在发生任何类型的上述异常时,程序将异常退出?或者程序会在没有提及任何内容的情况下执行此错误,因此难以调试错误?

像gcc这样的编译器是否能够为一些明显的情况发出警告?

在编写程序时,我可以做些什么来通知错误发生的位置以及发生错误时的类型,以便我可以在代码中轻松找到错误?请给出C和C++案例的解决方案.

感谢致敬!

Dig*_*oss 12

有很多选择,但754引入的一般和默认的理念是陷阱而是产生特殊的结果,例如在重要结果中可能会或可能不会出现的无穷大.

因此,测试各个操作状态的函数不会像测试结果表示的函数那样频繁使用.

例如,见......

LIST OF FUNCTIONS

 Each of the functions that use floating-point values are provided in sin-
 gle, double, and extended precision; the double precision prototypes are
 listed here.  The man pages for the individual functions provide more
 details on their use, special cases, and prototypes for their single and
 extended precision versions.

 int fpclassify(double)
 int isfinite(double)
 int isinf(double)
 int isnan(double)
 int isnormal(double)
 int signbit(double)
Run Code Online (Sandbox Code Playgroud)

更新:对于那些真正认为FPU ops在默认情况下生成SIGFPE的人,我鼓励你尝试这个程序.您可以轻松生成下溢,溢出和被零除.你不会生成什么(除非你在最后一个存活的VAX或非754 RISC上运行它)是SIGFPE:

#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av) { return printf("%f\n", atof(av[1]) / atof(av[2])); }
Run Code Online (Sandbox Code Playgroud)


Mik*_*ale 6

在Linux上,您可以使用GNU扩展名feenableexcept(隐藏在该页面底部)打开浮点异常的陷阱 - 如果您这样做,那么当发生异常时您将收到SIGFPE信号,然后您可以将其捕获你的调试器.当心,虽然因为有时信号大干快上的浮点指令抛出后,一个最实际造成问题的原因,给在调试器误导线的信息!