regression test suite

Started by nigelbrown, November 10, 2003, 06:18:14 PM

Previous topic - Next topic

nigelbrown

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

Lutz

#1
newLISP doesn't do any newLISP-specific i/o of integers (32 bits) or float (double float 64bits) but uses the 'C' language routines of the underlying OS's 'C' sompiler (Borland C-Builder for the Win32 version and GCC for all other versions).



For converting integers appearing in decimal format the function strtol() is used, for integers expressed in octal or hexadecimal format in the input stream, strtul() is used. Floats in there different formats (decimal or scientific/engineering) are all converted using the atof() function.



When displating numbers the usual printf() family (spritf, varprintf, etc. ) formatting routines are used. Floats, if not specifially formatted are output with the "%g" option (see the docs of the GCC compiler).



All arithmetik on numbers simply use the routines of the underlying 'C' compiler. Integer numbers are simply truncated, when they overflow 32 bits (31 + 1 sign bit).



Floating point arithmetik can cause NaN or Inf results for not allowed operations or under/over flow conditions. The way all these conditions are handled, again depends on the 'C' compiler, used to compile newLISP.



Before newLISP gets release a small collection of math routines is run. But these routines are more like a 'sanity' test, rather than testing specific cases.



Lutz

nigelbrown

#2
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

Lutz

#3
what is not acceptable is the decimal point behind the '1', but the following works:





>1E-1

0.1



>1E-10

1e-10



>1.0E-10

1e-10



You can use the decimal dot not on its own, but it would have to be followed by a number.



Lutz

Lutz

#4
I will try to change this, so a decimal point without following digit will be accepted.



Lutz

eddier

#5
According to ANSI C language syntax



.E-1



is not a valid floating point number.



Eddie

eddier

#6
According to

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



A floating point number looks like



6.1.3.1 Floating constants



    Floating constants[44]==



floating_constant:  $(F[45]E[46]?|D[47]+E[46])[flFL]?   [mkidn]



    This macro is invoked in definition 15.



    F[45]==



(D[47]*.D[47]+)



    This macro is invoked in definition 44.



    E[46]==



([eE][+-]?D[47]+)



    This macro is invoked in definition 44.



    D[47]==



[0-9]



    This macro is invoked in definitions 44, 45, 46, and 48.





Expand F[45] => [0-9]*.[0-9]+

Note that the "*" means it does not have to have a digit before the "." but the "+" after the [0-9]+ means their MUST be at least one digit following the "."



Eddie

Lutz

#7
I also made that change, so now missing digits before the decimal point are also accepted



> .5

0.5



and trailing decimal dot is not accepted in scientific E/e notation



> .E-1  ;; will be taken as a symbol

nil



I hope the newLISP reading of  floats is now completely ANSI C compliant.



Lutz

nigelbrown

#8
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

eddier

#9
???



I can't find the final either.



The gnu complier accepts .0e-1 or 0.e-1 but not .e-1



I don't know if gnu is following the ANSI standard.



Eddie

Lutz

#10
>>>

The gnu complier accepts .0e-1 or 0.e-1 but not .e-1

>>>



yes and this is how newLISP handles it now, the dot must have a digit at least on one side.



Lutz

nigelbrown

#11
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

Lutz

#12
>>>

Is that correct Lutz?

>>>



yes, pretty much.  This is what I did:



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

...


so a number can start sith a digit or a decimal point, but when it starts with a decimal point then please have a number digit after the decimal . (avoids accepting ".e-1")



I'll have a development release on the weekend with the addition of negative index/offsets in a variety of string/list primitives and the changes for floating point parsing.



Lutz



ps: very welcome to the group Nigel