[comp.os.msdos.programmer] Turbo C matherr

broehl@watserv1.waterloo.edu (Bernie Roehl) (08/01/90)

The problem is simple... maybe the solution will be, too.
I'm trying to define my own matherr() function, as described on page 242 of
the Reference Guide.

#include <math.h>

int matherr(struct exception *e)
	{
	fprintf(stderr, "Hello, world!\n");
	return 1;
	}

I then write a short program that just divides by zero, link it with the above,
and run it.  Instead of "Hello, world!\n", I get the standard Turboc C
"Floating point error: Divide by 0".

Any ideas/suggestions/etc will be much appreciated.  Thanks in advance...

-- 
	Bernie Roehl, University of Waterloo Electrical Engineering Dept
	Mail: broehl@watserv1.waterloo.edu OR broehl@watserv1.UWaterloo.ca
	BangPath: {allegra,decvax,utzoo,clyde}!watmath!watserv1!broehl
	Voice:  (519) 885-1211 x 2607 [work]

pete@Octopus.COM (Pete Holzmann) (08/03/90)

broehl@watserv1.waterloo.edu (Bernie Roehl) writes:
>The problem is simple... maybe the solution will be, too.
>I'm trying to define my own matherr() function, as described on page 242 of
>the Reference Guide.
>
>I then write a short program that just divides by zero, link it with the above,
>and run it.  Instead of "Hello, world!\n", I get the standard Turboc C
>"Floating point error: Divide by 0".
>
>Any ideas/suggestions/etc will be much appreciated.  Thanks in advance...

Unfortunately, the solution is not as simple as you would like.

matherr() only deals with the errors that it is documented to deal
with. Basically, it is only called when an error is generated within
the trig/exponential functions.

To handle divide by zero and a host of other problems, you must set
up a signal handler for SIG_FPE (see signal()). This also requires 
careful use of setjmp() and longjmp(). Which can be truly a pain in
the neck!

Pete
-- 
Peter Holzmann, Octopus Enterprises   |(if you're a techie Christian & are
19611 La Mar Ct., Cupertino, CA 95014 |interested in helping w/ the Great
UUCP: {hpda,pyramid}!octopus!pete     |Commission, email dsa-contact@octopus)
DSA office ans mach=408/996-7746;Work (SLP) voice=408/985-7400,FAX=408/985-0859

bobmon@iuvax.cs.indiana.edu (RAMontante) (08/03/90)

As Pete Holzmann says, matherr() only catches math errors in library
functions.  You must use the SIG_FPE/setjmp/longjmp facilities to
handle "lower-level" math errors.

I found that it was really hard to recover from a general math error ---
what do you want to do on divide-by-zero, for example?  Generate a
largest-possible-value? print a message? ... The simplest thing to do
is to simply clear everything out and longjmp back to some point in
your code that precedes the failed operation (and your error-handler
doesn't necessarily know where that is).

Plug:  I am told that my rpn calculator is queued for c.b.i.p.  It includes
source code, and I use both the matherr() and the SIG_FPE code to handle
math errors.  I don't claim it's the best example of such stuff, but it
*is* a working example...

broehl@watserv1.waterloo.edu (Bernie Roehl) (08/09/90)

Thanks for all the answers about matherr()... the bottom line seems to be that
I'll have to trap the errors using SIG_FPE instead of just writing my own
math handler.

Sigh.

-- 
	Bernie Roehl, University of Waterloo Electrical Engineering Dept
	Mail: broehl@watserv1.waterloo.edu OR broehl@watserv1.UWaterloo.ca
	BangPath: {allegra,decvax,utzoo,clyde}!watmath!watserv1!broehl
	Voice:  (519) 885-1211 x 2607 [work]