math exception handling

Q&A's, tips, howto's

math exception handling

Postby nigelbrown » Mon Nov 17, 2003 1:21 am

Hi all,
I've been looking into the math side of newlisp (that's my current interest in it) but
I don't see specified how newlisp handles floating point overflow exceptions.
From nl-math.c addition (for example) is done by:
CELL * floatOp(CELL * params, int operand)
{
double number;
double result;
double fltNum;
long intNum;

params = getFloat(params, &result);
if(params == nilCell)
{
if(operand == OP_SUBTRACT)
result = - result;
}
while(params != nilCell)
{
params = getFloat(params, &number);
switch(operand)
{
case OP_ADD: result += number; break

and early in the file there seems to be a "do nothing" exception handling established (fair enough default) viz:

#ifdef __BORLANDC__
int _matherr(struct _exception *e) {return 0;};
#endif

Now - causing an addition overflow crashes newlisp eg:

C:\newlisp>newlisp
newLISP v7.3.3 Copyright (c) 2003 Lutz Mueller. All rights reserved.

> 1.7976931348623157E308
1.797693135e+308
> (add 1.7976931348623157E308 0.1e308)

C:\newlisp>

I don't know what happens on linux. Can math exceptions be caught/handled in win32 newlisp? Could it gracefully die with an
error message? I don't have documentation on how
Borlands BCC55 uses matherr.
Regards
Nigel
nigelbrown
 
Posts: 429
Joined: Tue Nov 11, 2003 2:11 am
Location: Brisbane, Australia

Postby Lutz » Mon Nov 17, 2003 2:40 am

In newLISP math exceptions are best handled on the UNIX compiles (LINUX, FreeBSD) on these platforms you would get:

(add 1.7976931348623157E308 0.1e308) => inf

without crashing handled well by the GCC compiler on these platforms.

When compiling with CYGWIN (UNIX simulation on Win32) you get:

(add 1.7976931348623157E308 0.1e308) => Inf

but BCC on Win32 crashes, on the previous example (seems to be a bug in BCC libraries), but produces +INF on other overflow conditions, i.e 1e1000 = > +INF

(sqrt -1) => NaN

works well on all platforms and there is a function NaN? in newLISP to test for it.

(/ 123 0) => 'division by zero'

throws a 'division by 0' error on all platforms (trapped by newLISP)

For Math, LINUX or another UNIX compiles using GCC is the preferred way to go. If you want to use Windows, the best way is to compile newLISP for CYGWIN, it also gives you the possibility (like on UNIX) to treat network sockets as filehandles.

Another possibility is, to have newLISP run on a remote UNIX machine and connect to it from a Windows machine via the network. This works with both, the console version of newLISP and the newLISP-tk frontend, which also can connect to a remote running newLISP. Both alternatives are documented in the manuals.

By the way: 5.e-1, 5e-1, .5e-1 etc. are now all working fine on 7.3.3.

Lutz
Lutz
 
Posts: 5276
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California

Postby nigelbrown » Mon Nov 17, 2003 4:10 am

Hi Lutz,
Thanks for the 1.e-1 stuff - I'm using it already.
Its interesting that compiling
int main()
{ double d;
d = 1e308 + 1e308;
printf("number:%g",d);
return 0;
}
with the borland compiler and running gives:
C:\newlisp\NEWLIS~2>c:\Borland\BCC55\Bin\make testmath.c
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland

C:\newlisp\NEWLIS~2>c:\Borland\BCC55\Bin\bcc32.exe testmath.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
testmath.c:
Warning W8065 testmath.c 4: Call to function 'printf' with no prototype in func
ion main
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

C:\newlisp\NEWLIS~2>testmath
number:+INF
C:\newlisp\NEWLIS~2>

That is +INF is returned - perhaps the error is in += as the code does:
case OP_ADD: result += number; break;

but
I just tested:
int main()
{ double d;
d = 1e308 ;
d += 1e308;
printf("number:%g",d);
return 0;
}
which throws a floating point overflow error and terminates the program.

That suggests that
case OP_ADD: result = result + number; break;
should work
but when I make that change (I think) to n-math.c I still get an error -
perhaps somewhere else?
I'm using XP Pro.
Regards
Nigel
nigelbrown
 
Posts: 429
Joined: Tue Nov 11, 2003 2:11 am
Location: Brisbane, Australia

Postby nigelbrown » Mon Nov 17, 2003 8:23 am

Please excuse some of the oversights in my last post -
a compile would replace = 1e308 + 1e308 with aconstant assignment,
not an addition -
I'll look further at it.
Regards
Nigel
nigelbrown
 
Posts: 429
Joined: Tue Nov 11, 2003 2:11 am
Location: Brisbane, Australia


Return to newLISP in the real world

Who is online

Users browsing this forum: No registered users and 1 guest

cron