www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/07/03/09:15:51

From: Waldemar Schultz <schultz AT ma DOT tum DOT de>
Newsgroups: comp.os.msdos.djgpp
Subject: Floating point exception
Date: Mon, 03 Jul 2000 15:02:46 +0200
Organization: [posted via] Leibniz-Rechenzentrum, Muenchen (Germany)
Lines: 95
Message-ID: <39608EF6.FC0856D1@ma.tum.de>
NNTP-Posting-Host: pcritter10.mathematik.tu-muenchen.de
Mime-Version: 1.0
X-Trace: wsc10.lrz-muenchen.de 962629413 23930 131.159.69.74 (3 Jul 2000 13:03:33 GMT)
X-Complaints-To: news AT lrz-muenchen DOT de
NNTP-Posting-Date: 3 Jul 2000 13:03:33 GMT
X-Mailer: Mozilla 4.73 [de]C-CCK-MCD DT (Win98; U)
X-Accept-Language: de,en,en-US
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Hi experts,
I am messing around with huge nmumerical programs and I need to implement FPE
on any abnormal FP operation. What I did up to now you can see below.
Would somone please have a look to the example and comment/correct it.

The second problem is: is it possible to throw an exception when a number
becomes NaN (NOTaNUMBER) ir Inf (Infinite) ?

any help greatly appreciated. Thanks.

(sorry for the lengthy snippet, but it's minimal)

--- (DOS/gcc 2.95.2) gcc -W -Wall -g sigfpe.c -o sigfpe.exe -lm ---

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <float.h>

static volatile unsigned int Mcw; //MasterControlWord
static void(* Fpe)(int)=NULL;     //pointer to save current FPE-Handler

static void FloatError(int sig)
{
unsigned int sw;

 sig=sig; //shutup
 sw=_status87();
 if(sw & Mcw)
 {
  fflush(stdout);
  fprintf(stderr,"Floating Point Exception: \a [ "  );
  if(sw & SW_INVALID)    fprintf(stderr,"INVALID "  );
  if(sw & SW_DENORMAL)   fprintf(stderr,"DENORMAL " );
  if(sw & SW_ZERODIVIDE) fprintf(stderr,"DIVBYZERO ");
  if(sw & SW_OVERFLOW)   fprintf(stderr,"OVERFLOW " );
  if(sw & SW_UNDERFLOW)  fprintf(stderr,"UNDERFLOW ");
  //if(sw & SW_INEXACT)  fprintf(stderr,"INEXACT "  );
  fprintf(stderr,"]\n"                              );
  fflush(stderr);
  _clear87();
  _fpreset();
  signal(SIGFPE,Fpe);   // floating point
  raise(SIGABRT);
 }
 _clear87();
}


#include <math.h>

static void sigfpe(void)
{
 if(Fpe) return; //don't do that twice

 Mcw = 0
    | EM_INVALID
    | EM_DENORMAL
    | EM_ZERODIVIDE
    | EM_OVERFLOW
    | EM_UNDERFLOW
//  | EM_INEXACT
    ;

 _fpreset();
 _control87(~Mcw,Mcw);
 _clear87();
 Fpe=signal(SIGFPE,FloatError);   // save FPE hander function pointer
}

static void unsigfpe(void)
{
 if(!Fpe) return; //don't do that twice

 _control87(MCW_EM,MCW_EM);
 _clear87();
 _fpreset();
 signal(SIGFPE,Fpe);   // floating point
}

int main(void)
{
long double a=1.0, b=0.0, y;

 sigfpe();
 y=log(b); printf("%Lg\n",y); //-Inf no FPE :-(
 a=a/b;                       //FPE signalled
 unsigfpe();
 return 0;
}

-- 
 Gruss Waldemar Schultz.
 Technische Universität München, Zentrum Mathematik M1, D 80290 München
 Tel: +49 (0)89 2892 8226        FAX: +49 (0)89 2892 8228

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019