Following function is usable from C and FORTRAN and is sitting the
library /astro3_d/sanjay/gmrtdata/sanb_prog/new/calc.o. The include
file is also sitting in the same area. This function will also
require /usr/lib/libl.a.
Have fun.
sanjay
8><------------------------------------------------------------------------><8
Name
calc,calcufunc
SYNOPSIS
#include
int calc(char *exp, double *result);
void calcufunc(double (*func)(char *));
DESCRIPTION
calc is a function which encapsulates a parser for evaluating
mathematical expressions. The expression is given as a NULL
terminated char string "exp". The result of the expression is
returned in *result.
If the return value of of calc is 0, it was able to evaluate
the given expression. If the return value is -1, there was
some parsing error. In this case it will also print an error
message of the stderr, pointing to the character in the string
exp where it "thinks" is the trouble.
The parser understands the following functions:
sin,cos,tan,asin,acos,atan,atan2,sinh,cosh,tanh,exp,
ln,log (both natural log),log10,sqrt,fabs,floor,
ceil,rint
It also understands the following constants:
PI
C speed of light in m/s.
R2D,D2R for conversion from Radians to Deg. and vice
versa
H2R,R2H for conversion from Hours to Radians and vice
versa
SOL2SID,SID2SOL for conversion from Solar to Sidreal
time
It understand number in the following formats:
Integer foramt, real (float) format
1.0E-1 or 1.0e-1 (=0.1)
1.0D-1 or 1.0d-1 (=0.1)
1h10m0.1s (the HA format - converts the number
to no. of hours)
1d1"1' (the angular format - convertst to
no. of degrees)
(1d1" = 1.0166666667 deg. and -1d1" = -1.01666666667 deg.)
calcfunc is used to tell the parser the function to call in
case of unresolved variables. If the parser in unable to
resolve a variable in the expression, it checks if the user
defined function is set. If it is set, it makes a call to the
user define function, which is expected to return the value of
the variable passed to it. If the user define function is not
set, the parser gives an error message and returns -1.
Use of calcfunc allows the user to extend the effective
symbol table to any length. Since the internal (intrensic)
symbol table is fairly small, calc does a liner search for
lookup in the symbol table. However, if the symbol table
grows too large, linear search may not be the way to go.
Since the extension of the symbol table is also done from
outside, in case the "external" variable list is large, the
user can also implement a smarter search in the external
routine.
The user defined function takes one argument of type "char *"
and return a double (the value of the variable).
calc can be used in place of sscanf - where ease of giving
numbers to a program is important (usually while reading a
number from a human). Wherever calc is used to convert a
string into a number, the string can be an expression of any
depth.
PENDING WORK
o The symbol table, at present can be extended only for
variables (and not for functions). This mechanism has to be
extended for functions with arbitrary number of arguments.
o calc routine run approximately 3 times slower with respect to
sscanf when used to JUST do the job that sscanf could have
done. The loss of speed is partly due to the fact the calc is
doing more work (parsing the string) than sscanf, but is in
turn giving more power to the user.
Following are the top functions in which 10000 calls to calc
spent most of the time.
%Time Seconds Cumsecs #Calls msec/call Name
20.0 0.23 0.23 getenv
18.5 0.21 0.44 20000 0.0106 yylook
10.4 0.12 0.56 10000 0.0120 _file_to_decimal
10.3 0.12 0.68 _mcount
7.8 0.09 0.77 10000 0.0090 __doscan_u
6.0 0.07 0.84 10000 0.0069 yyparse
5.2 0.06 0.90 20000 0.0030 strncpy
4.3 0.05 0.95 80000 0.0006 strlen
2.6 0.03 0.98 20000 0.0015 strcmp
2.2 0.03 1.01 10000 0.0026 calc
1.9 0.02 1.03 20000 0.0011 yylex
yylook,yyparse and yylex are the calls of the parser and I
think very little can be done about them. However, I do not
understand the calls made to getenv! If one understands where
and why are these calls to getenv made and eleminate them,
calc can be made ~20% faster.