Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - nigelbrown

#421
newLISP in the real world /
November 17, 2003, 08:29:09 PM
Thank you Lutz for your speedy response.

I was thinking that perhaps the behaviour regarding floating point error signals should be a compile time option (I don't know that runtime setting of this behaviour is justified - what do you think?).

Code for making GCC adopt the current borland behavior of NOT masking exceptions is given here:

http://www.fortran-2000.com/ArnaudRecipes/CompilerTricks.html#Glibc_FP">http://www.fortran-2000.com/ArnaudRecip ... l#Glibc_FP">http://www.fortran-2000.com/ArnaudRecipes/CompilerTricks.html#Glibc_FP

(more or less -it is actually a discussion for when gcc is used as backend for fortran g77)

Viz:

#include <fenv.h>

static void __attribute__ ((constructor)) trapfpe(void)

{

  /* Enable some exceptions. At startup all exceptions are masked. */

  feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);

}



When thinking about it I decided I might like to be alerted to overflow rather than having +INF slipped in - but perhaps with a catching of SIGFPE followed by a graceful termination with an error message.

Thoughts?



Nigel
#422
newLISP in the real world /
November 17, 2003, 05:45:13 PM
In aprt answer to my previous post-

 the function|

#include <float.h>



unsigned int _control87(unsigned int newcw, unsigned int mask);



Description

This function sets and retrieves the FPU's control word.

described at:



http://www.ludd.luth.se/~ams/djgpp/cvs/djgpp/src/libc/pc_hw/fpu/cntrl87.txh">http://www.ludd.luth.se/~ams/djgpp/cvs/ ... ntrl87.txh">http://www.ludd.luth.se/~ams/djgpp/cvs/djgpp/src/libc/pc_hw/fpu/cntrl87.txh



can be used to mask FPU exceptions and enable internal FPU processing of exceptions as below:

A masked exception will be handled internally by the

coprocessor.  In general, that means that it will generate special

results, such as @dfn{NaN}, Not-a-Number (e.g., when you attempt to

compute a square root of a negative number), denormalized result (in

case of underflow), or infinity (e.g., in the case of division by zero,

or when the result overflows).



It would appear that by default gcc masks exceptions while Borland does  not (and the pros and cons of such defaults could be argued).

Looks like it becomes just a matter of enabling FPU internel exception handling at the start of Borland code to bring GCC and BCC into line.

Regards

Nigel
#423
newLISP in the real world / SIGFPE signal handling
November 17, 2003, 05:22:14 PM
Hi,

I've started a new thread as signal handling is the issue

 with (add 1e308 1e308) terminating newlisp.

Borland's default for catching a SIGFPE (floating point exception signal)

is program termination (that is, the library's action is a "feature" not a bug?).

From the borland help docs I pasted some code that catches the SIGFPE

and noew get:



newLISP v7.3.3 Copyright (c) 2003 Lutz Mueller. All rights reserved.



> (add 1e308 1e308)

Caught it!

1e+308

>

the diff format comparison below shows the inserted signal handling code,

I don't know if you want to include signal handling for the Borland compile

or write it off as a Borland 'feature'

Regards

Nigel

Examdiff Diff output: nl-math.c v7303 vs v7301

56c56,76

< int _matherr(struct _exception *e) {return 0;};

---

> int _matherr(struct _exception *e) {return 0;};

> /* try catch floating point exception signal */

> #include <signal.h>

>

> #ifdef __cplusplus

>    typedef void (*fptr)(int);

> #else

>    typedef void (*fptr)();

>

> #endif

>

>

>

> void Catcher()

> {

>    signal(SIGFPE, (fptr)Catcher);  //  ******reinstall signal handler

>

>    printf("Caught it!n");

> }

>

> /* signal(SIGFPE, (fptr)Catcher);  install catcher later*/

192a213

> #ifdef __BORLANDC__

193a215,216

>  signal(SIGFPE, (fptr)Catcher); /* install catcher */

> #endif

204a228

>    /*   case OP_ADD:            result += number; break; */
#424
newLISP in the real world /
November 17, 2003, 12:23:45 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
#425
newLISP in the real world /
November 16, 2003, 08:10:38 PM
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:newlispNEWLIS~2>c:BorlandBCC55Binmake testmath.c

MAKE Version 5.2  Copyright (c) 1987, 2000 Borland



C:newlispNEWLIS~2>c:BorlandBCC55Binbcc32.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:newlispNEWLIS~2>testmath

number:+INF

C:newlispNEWLIS~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
#426
newLISP in the real world / math exception handling
November 16, 2003, 05:21:16 PM
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
#427
Anything else we might add? /
November 12, 2003, 03:35:29 PM
Thanks Lutz and Eddier, much appreciated.



For my information and understanding of newlisp I looked at the code and

presume the adjustment you made must be in the getToken function

of newlisp.c about the code:

   if(*stream->ptr == '.' && isDigit(*(stream->ptr+1)) )

      {

      *(tkn++) = *(stream->ptr++), tknLen++;

      while(isDigit(*stream->ptr) && tknLen < MAX_SYMBOL)

         *(tkn++) = *(stream->ptr++), tknLen++;

      floatFlag = TRUE;

      }

   else if(toupper(*stream->ptr) != 'E')

      {

      *tkn = 0;

      return(TKN_DECIMAL);

      

Is that correct Lutz?

Regards

Nigel
#428
Anything else we might add? /
November 12, 2003, 12:17:06 PM
Thank you for handling this question and Eddier thanks for the

http://www.cs.colorado.edu/~eliuser/c_html/c.html#m43">http://www.cs.colorado.edu/~eliuser/c_html/c.html#m43 link.

I'm not an ANSI C expert but I think the definition used in the lint macros

quoted viz: http://www.cs.colorado.edu/~eliuser/c_html/c.html#m43">http://www.cs.colorado.edu/~eliuser/c_html/c.html#m43

is incorrect regarding the requirement for trailing digits after the .

the extract below from the ANCSI C Committee Draft — August 3, 1998 WG14/N843 (couldn't find final) doc at http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n843.pdf">http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n843.pdf

says:

decimal-floating-constant:

     fractional-constant exponent-part opt floating-suffixopt

     digit-sequence exponent-part floating-suffixopt

...

fractional-constant:

    digit-sequenceopt . digit-sequence

    digit-sequence .

exponent-part:

    e signopt digit-sequence

    E signopt digit-sequence

sign: one of

    + -

digit-sequence:

    digit

    digit-sequence digit



which has "   digit-sequenceopt . digit-sequence"

or "    digit-sequence . " as acceptable fractional parts thus the lcc c compiler atof() accepting 1.E-1

that is there NEED NOT be at least one digit following the "."



Thanks Lutz for the changes

Regards

Nigel
#429
Anything else we might add? / re:regression test suite
November 11, 2003, 04:09:07 PM
I was thinking more of how the lisp reader selects the text to go for conversion.

I don't have C-Builder but

printf("number= %g", atof("1.E-1"));

in the lcc c compiler prints :

number= 0.1

while in newlisp we get

> 1.E-1

1nil

>

and:



> (add 1.E-1 1.E-1)



value expected in function add : .E-1



> (add 1.0E-1 1.0E-1)

0.2

>



should 1.E-1 be acceptable in ANSI-C? and thus to newlisp?

Regards

Nigel
#430
Anything else we might add? / regression test suite
November 10, 2003, 06:18:14 PM
Can anyone point to a lisp set of tests that test for reading of floats, their manipulation, and output. I've seen the GCL tests but they don't seem to test the basic number i/o. I was thinking of more a real world test (maybe read and manipulate data to give defined output file) or an extensive i/o test. Basically to do regression tests on new versions to maintain confidence that numerical i/o and processing is consistent across versions.

Nigel