2011-04-12 20 views
12

Uygulamamın hatalarını ayıklamak için (fortran 90) Tüm NaN'leri NaN sinyalini vermek istiyorum. Varsayılan ayarları ileÖnce programlamayı durdurmak için gfortranı zorla NaN

programım işaretlerine olmadan çalışır ve sadece dosyadaki NaN verileri çıktı. NaN'nin üretildiği noktayı bulmak istiyorum. NaN sinyali ile programı yeniden derleyebilirsem, ilk yanlış kayan işlemin bulunduğu ilk noktada bir SIGFPE sinyali alacağım.

cevap

21

aradığınız bayrak -ffpe-trap=invalid olduğu; İlgili kayan nokta istisnalarını kontrol etmek için genellikle ,zero,overflow eklerim.

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 

Sonra onun derlenmesi ve ayıklayıcısında çalıştırmaya

verir: Aynı şeyi yapacağım seçeneği -fpe0 kullanarak intel fortran derleyici (ifort) ile

$ 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 

.

Bu C/C++ kodu ile küçük bir tıkırtı; Aslında, kayan nokta istisnalarını etkinleştiren ve fenv.h'da tanımlanmış olan feenableexcept() numaralı aramaya bir arama eklememiz gerekir;

#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\n", a, b, c); 

    a = 0.; 
    b = 0.; 

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

    a = 2.; 
    b = 1.; 

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

    return 0; 
} 

ama etkisi aynı:

$ 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; 

her iki şekilde, hatalarının ortaya çıkan yere bağlı çok daha iyi bir kolu var.

+0

Merhaba, g ++ ile aynı seçeneği uygulamak mümkün mü? – osgx

+2

g ++ ile daha zor, ancak kayan nokta hataları üzerinde tuzakları ayarlamak mümkündür - http://trac.hackerwithin.org/wiki/Articles/GccFpe –

İlgili konular