diff --git a/check/features.frm b/check/features.frm index 04be478b..dc2153fe 100644 --- a/check/features.frm +++ b/check/features.frm @@ -594,7 +594,7 @@ assert result("F", 3) =~ expr(" *--#] Format_noreset_linelen : *--#[ evaluate_symbol : #- -#StartFloat 64 +#StartFloat 64b Symbol a,b; Local PI0 = a*b; @@ -629,7 +629,7 @@ assert result("EM1") =~ expr("5.77215664901532860607e-01") *--#] evaluate_symbol : *--#[ evaluate_symbol_pi : #- -#StartFloat 128 +#StartFloat 128b Local PI = pi_; Local EE = ee_; @@ -647,7 +647,7 @@ assert result("EM") =~ expr("1.0e+00*em_") *--#] evaluate_symbol_pi : *--#[ evaluate_symbol_ee : #- -#StartFloat 160 +#StartFloat 160b Local PI = pi_; Local EE = ee_; @@ -665,7 +665,7 @@ assert result("EM") =~ expr("1.0e+00*em_") *--#] evaluate_symbol_ee : *--#[ evaluate_symbol_em : #- -#StartFloat 192 +#StartFloat 192b Local PI = pi_; Local EE = ee_; diff --git a/doc/manual/float.tex b/doc/manual/float.tex index 9daaa17e..4c4cdf9f 100644 --- a/doc/manual/float.tex +++ b/doc/manual/float.tex @@ -12,10 +12,12 @@ \chapter{Floating point} point system. Invoking it will allocate a number of arrays. The instruction has either one or two arguments: \begin{verbatim} - #startfloat numberofbits <,maximumweight> + #startfloat [,MZV=] \end{verbatim} -The first argument is mandatory. It tells how many bits of accuracy are -required. \FORM{} will round to at least this precision. Because the internal +The first argument is mandatory and specifies the desired precision. It must +be a positive integer followed by either \texttt{b} (for precision in bits) +or \texttt{d} (for precision in decimal digits). +\FORM{} will round to at least this precision. Because the internal routines work with WORDs the precision will be rounded up to the nearest integer number of WORDs. The second argument is optional for when one wants to work with multiple zeta values (MZVs) or Euler sums. It specifies the @@ -65,7 +67,7 @@ \chapter{Floating point} The following example shows some work with Multiple Zeta Values (MZV's): \begin{verbatim} - #StartFloat 500,15 + #StartFloat 500b, MZV=15 L F1 = -mzv_(8,1,1,5) +29056868/39414375*mzv_(2)^6*mzv_(3) diff --git a/doc/manual/prepro.tex b/doc/manual/prepro.tex index 44d3f523..c7fc9aac 100644 --- a/doc/manual/prepro.tex +++ b/doc/manual/prepro.tex @@ -935,6 +935,18 @@ \section{\#enddo} do\index{do loop} loop. See the \#do\index{\#do} instruction. %--#] enddo : +%--#[ endfloat : + +\section{\#endfloat} +\label{preendfloat} + +\noindent Syntax: + +\#endfloat + +\noindent See also startfloat (\ref{prestartfloat}) and chapter~\ref{floatingpoint} on the floating point capacity. + +%--#] endfloat : %--#[ endif : \section{\#endif} @@ -1960,6 +1972,18 @@ \section{\#sortreallocate} \FORM's memory usage as measured by ``resident set size''. %--#] sortreallocate : +%--#[ startfloat : + +\section{\#startfloat} +\label{prestartfloat} + +\noindent Syntax: + +\#startfloat $<$precision$>$ [,MZV=$<$weight$>$] + +\noindent See also endfloat (\ref{preendfloat}) and chapter~\ref{floatingpoint} on the floating point capacity. + +%--#] startfloat : %--#[ switch : \section{\#switch} diff --git a/doc/manual/statements.tex b/doc/manual/statements.tex index b61b63e9..940e24ed 100644 --- a/doc/manual/statements.tex +++ b/doc/manual/statements.tex @@ -1478,6 +1478,18 @@ \section{endwhile} module. \vspace{10mm} %--#] endwhile : +%--#[ evaluate : +\section{evaluate} +\label{substaevaluate} + +\noindent \begin{tabular}{ll} +Type & Executable statement\\ +Syntax & evaluate [$<$function name$>$]; \\ +\end{tabular} \vspace{4mm} + +\noindent See chapter~\ref{floatingpoint} on the floating point capacity. + +%--#] evaluate : %--#[ exit : \section{exit} @@ -5832,6 +5844,18 @@ \section{threadbucketsize} `ON,setup;' statement (\ref{substaon} and \ref{setup}). \vspace{10mm} %--#] threadbucketsize : +%--#[ tofloat : +\section{tofloat} +\label{substatofloat} + +\noindent \begin{tabular}{ll} +Type & Executable statement\\ +Syntax & tofloat; +\end{tabular} \vspace{4mm} + +\noindent See chapter~\ref{floatingpoint} on the floating point capacity. + +%--#] tofloat : %--#[ topolynomial : \section{topolynomial} @@ -5865,6 +5889,18 @@ \section{topolynomial} \vspace{10mm} %--#] topolynomial : +%--#[ torational : +\section{torational} +\label{substatorational} + +\noindent \begin{tabular}{ll} +Type & Executable statement\\ +Syntax & torational; +\end{tabular} \vspace{4mm} + +\noindent See chapter~\ref{floatingpoint} on the floating point capacity. + +%--#] torational : %--#[ tospectator : \section{tospectator} diff --git a/sources/pre.c b/sources/pre.c index 9c6a15af..342c2144 100644 --- a/sources/pre.c +++ b/sources/pre.c @@ -32,6 +32,9 @@ #[ Includes : */ #include "form3.h" +#ifdef WITHFLOAT +#include "math.h" +#endif static UBYTE pushbackchar = 0; static int oldmode = 0; @@ -7691,20 +7694,41 @@ int DoStartFloat(UBYTE *s) error = 1; } while ( *s == ',' || *s == ' ' || *s == '\t' ) s++; +/* + The first parameter is the float precision +*/ if ( *s >= '0' && *s <= '9' ) { x = 0; do { x = 10*x + (*s++-'0'); } while ( *s >= '0' && *s <= '9' ); - AC.tDefaultPrecision = x; +/* + The precision can either be in digits or bits. + AC.DefaultPrecision is always in bits. +*/ + if ( tolower(*s) == 'd' ) { AC.tDefaultPrecision = x*log2(10.0); s++; } + else if ( tolower(*s) == 'b' ) { AC.tDefaultPrecision = x; s++; } + else goto IllPar; while ( *s == ',' || *s == ' ' || *s == '\t' ) s++; - if ( *s >= '0' && *s <= '9' ) { - x = 0; - do { - x = 10*x + (*s++ - '0'); - } while ( *s >= '0' && *s <= '9' ); - AC.tMaxWeight = x; - while ( *s == ',' || *s == ' ' || *s == '\t' ) s++; +/* + The second parameter is either absent, which implies zero MZV weight, + or of the form MZV = +*/ + if ( tolower(*s) == 'm' && tolower(s[1]) == 'z' && tolower(s[2]) == 'v') { + s+=3; + while ( *s == ' ' || *s == '\t' ) s++; + if ( *s != '=') goto IllPar; + s++; + while ( *s == ' ' || *s == '\t' ) s++; + if ( *s >= '0' && *s <= '9' ) { + x = 0; + do { + x = 10*x + (*s++ - '0'); + } while ( *s >= '0' && *s <= '9' ); + AC.tMaxWeight = x; + while ( *s == ',' || *s == ' ' || *s == '\t' ) s++; + } + else goto IllPar; } else { AC.tMaxWeight = 0;