强制 gfortran 在第一个 NaN 处停止程序 [英] Force gfortran to stop program at first NaN

查看:26
本文介绍了强制 gfortran 在第一个 NaN 处停止程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了调试我的应用程序 (fortran 90),我想将所有 NaN 转换为信号 NaN.

To debug my application (fortran 90) I want to turn all NaNs to signalling NaN.

使用默认设置,我的程序在没有任何信号的情况下工作,只在文件中输出 NaN 数据.我想找到生成 NaN 的点.如果我可以用信号 NaN 重新编译程序,我将在第一个错误浮动操作所在的第一个点得到一个 SIGFPE 信号.

With default settings my program works without any signals and just outputs NaN data in file. I want find the point, where NaN is generated. If I can recompile program with signalling NaN, I will get an SIGFPE signal at first point where first wrong floating operation reside.

推荐答案

你要找的标志是 -ffpe-trap=invalid;我通常添加 ,zero,overflow 来检查相关的浮点异常.

The flag you're looking for is -ffpe-trap=invalid; I usually add ,zero,overflow to check for related floating point exceptions.

program nantest
    real :: a, b, c

    a = 1.
    b = 2.

    c = a/b
    print *, c,a,b

    a = 0.
    b = 0.

    c = a/b
    print *, c,a,b

    a = 2.
    b = 1.

    c = a/b
    print *,c,a,b
end program nantest

然后编译它并在调试器中运行它会得到:

Then compiling it and running it in a debugger gives:

$ gfortran -o nantest nantest.f90 -ffpe-trap=invalid,zero,overflow -g -static
$ gdb nantest
[...]
(gdb) run
Starting program: /scratch/ljdursi/Testing/fortran/nantest 
  0.50000000       1.0000000       2.0000000    

Program received signal SIGFPE, Arithmetic exception.
0x0000000000400384 in nantest () at nantest.f90:13
13          c = a/b
Current language:  auto; currently fortran

使用 intel fortran 编译器 (ifort),使用选项 -fpe0 会做同样的事情.

With the intel fortran compiler (ifort), using the option -fpe0 will do the same thing.

C/C++ 代码有点小技巧;我们必须实际插入对 feenableexcept() 的调用,它启用浮点异常,并在 fenv.h 中定义;

It's a little tricker with C/C++ code; we have to actually insert a call to feenableexcept(), which enables floating point exceptions, and is defined in fenv.h;

#include <stdio.h>
#include <fenv.h>

int main(int argc, char **argv) {  
    float a, b, c;
    feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

    a = 1.;
    b = 2.;

    c = a/b;
    printf("%f %f %f
", a, b, c);

    a = 0.;
    b = 0.;

    c = a/b;
    printf("%f %f %f
", a, b, c);

    a = 2.;
    b = 1.;

    c = a/b;
    printf("%f %f %f
", a, b, c);

    return 0;
}

但效果是一样的:

$ gcc -o nantest nantest.c -lm -g
$ gdb ./nantest
[...]
(gdb) run
Starting program: /scratch/s/scinet/ljdursi/Testing/exception/nantest  
1.000000 2.000000 0.500000

Program received signal SIGFPE, Arithmetic exception.  
0x00000000004005d0 in main (argc=1, argv=0x7fffffffe4b8) at nantest.c:17  
17        c = a/b;  

无论哪种方式,您都可以更好地处理错误发生的位置.

either way, you have a much better handle on where the errors are occuring.

这篇关于强制 gfortran 在第一个 NaN 处停止程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆