/* * fmath.c -- sin, cos, tan, acos, asin, atan, dtor, rtod, exp, log, sqrt */ #include #include "..\h\config.h" #include "..\h\rt.h" #include "rproto.h" #ifdef MathFncs /* * The following code is operating-system dependent [@fmath.01]. Include * system-dependent files and declarations. */ #if PORT /* probably #include */ #endif /* PORT */ #if AMIGA || HIGHC_386 || MACINTOSH || VMS #include #endif /* AMIGA || HIGHC_386 ... */ #if ATARI_ST #if LATTICE #include #else /* LATTICE */ #include #endif /* LATTICE */ #endif /* ATARI_ST */ #if MSDOS #if !MWC #include #endif /* !MWC */ #if MICROSOFT int errno; #endif /* MICROSOFT */ #endif /* MSDOS */ #if OS2 #if MICROSOFT int errno; #endif /* MICROSOFT */ #endif /* OS2 */ #if MVS || VM #include #ifdef SASC #include #define PI M_PI #endif /* SASC */ #endif /* MVS || VM */ #if UNIX #include int errno; #endif /* UNIX */ /* * End of operating-system specific code. */ #ifndef PI #define PI 3.14159 #endif /* PI */ /* * sin(x), x in radians */ FncDcl(sin,1) { int t; double sin(); if ((t = cvreal(&Arg1)) == CvtFail) RunErr(102, &Arg1); if (makereal(sin(BlkLoc(Arg1)->realblk.realval), &Arg0) == Error) RunErr(0, NULL); Return; } /* * cos(x), x in radians */ FncDcl(cos,1) { int t; if ((t = cvreal(&Arg1)) == CvtFail) RunErr(102, &Arg1); if (makereal(cos(BlkLoc(Arg1)->realblk.realval), &Arg0) == Error) RunErr(0, NULL); Return; } /* * tan(x), x in radians */ FncDcl(tan,1) { int t; double y; if ((t = cvreal(&Arg1)) == CvtFail) RunErr(102, &Arg1); errno = 0; y = tan(BlkLoc(Arg1)->realblk.realval); if (errno == ERANGE) RunErr(-204, NULL); if (makereal(y, &Arg0) == Error) RunErr(0, NULL); Return; } /* * acos(x), x in radians */ FncDcl(acos,1) { int t; double r, y; if ((t = cvreal(&Arg1)) == CvtFail) RunErr(102, &Arg1); r = BlkLoc(Arg1)->realblk.realval; if (r < -1.0 || r > 1.0) /* can't count on library */ RunErr(205,&Arg1); errno = 0; y = acos(r); if (errno == EDOM) RunErr(-205, NULL); if (makereal(y, &Arg0) == Error) RunErr(0, NULL); Return; } /* * asin(x), x in radians */ FncDcl(asin,1) { int t; double r, y; if ((t = cvreal(&Arg1)) == CvtFail) RunErr(102, &Arg1); r = BlkLoc(Arg1)->realblk.realval; if (r < -1.0 || r > 1.0) /* can't count on library */ RunErr(205,&Arg1); errno = 0; y = asin(r); if (errno == EDOM) RunErr(-205, NULL); if (makereal(y, &Arg0) == Error) RunErr(0, NULL); Return; } /* * atan(x,y) -- x,y in radians; if y is present, produces atan2(x,y). */ FncDcl(atan,2) { int t; if ((t = cvreal(&Arg1)) == CvtFail) RunErr(102, &Arg1); if (ChkNull(Arg2)) { if (makereal(atan(BlkLoc(Arg1)->realblk.realval), &Arg0) == Error) RunErr(0, NULL); } else { if ((t = cvreal(&Arg2)) == CvtFail) RunErr(102, &Arg2); if (makereal(atan2(BlkLoc(Arg1)->realblk.realval, BlkLoc(Arg2)->realblk.realval), &Arg0) == Error) RunErr(0, NULL); } Return; } /* * dtor(x), x in degrees */ FncDcl(dtor,1) { if (cvreal(&Arg1) == CvtFail) RunErr(102, &Arg1); if (makereal(BlkLoc(Arg1)->realblk.realval * PI / 180, &Arg0) == Error) RunErr(0, NULL); Return; } /* * rtod(x), x in radians */ FncDcl(rtod,1) { if (cvreal(&Arg1) == CvtFail) RunErr(102, &Arg1); if (makereal(BlkLoc(Arg1)->realblk.realval * 180 / PI, &Arg0) == Error) RunErr(0, NULL); Return; } /* * exp(x) */ FncDcl(exp,1) { int t; double y; if ((t = cvreal(&Arg1)) == CvtFail) RunErr(102, &Arg1); errno = 0; y = exp(BlkLoc(Arg1)->realblk.realval); if (errno == ERANGE) RunErr(-204, NULL); if (makereal(y, &Arg0) == Error) RunErr(0, NULL); Return; } /* * log(x,b) - logarithm of x to base b. */ FncDcl(log,2) { static double lastbase = 0.0; static double divisor; double x; if (cvreal(&Arg1) != T_Real) RunErr(102, &Arg1); if (BlkLoc(Arg1)->realblk.realval <= 0.0) RunErr(205, &Arg1); x = log(BlkLoc(Arg1)->realblk.realval); if (! ChkNull(Arg2)) { if (cvreal(&Arg2) != T_Real) RunErr(102, &Arg2); if (BlkLoc(Arg2)->realblk.realval <= 1.0) RunErr(205, &Arg2); if (BlkLoc(Arg2)->realblk.realval != lastbase) { divisor = log(BlkLoc(Arg2)->realblk.realval); lastbase = BlkLoc(Arg2)->realblk.realval; } x = x / divisor; } if (makereal(x, &Arg0) == Error) RunErr(0, NULL); Return; } /* * sqrt(x) */ FncDcl(sqrt,1) { int t; double r, y; if ((t = cvreal(&Arg1)) == CvtFail) RunErr(102, &Arg1); r = BlkLoc(Arg1)->realblk.realval; if (r < 0) RunErr(205, &Arg1); y = sqrt(r); errno = 0; if (errno == EDOM) RunErr(-205, NULL); if (makereal(y, &Arg0) == Error) RunErr(0, NULL); Return; } #else /* MathFncs */ static char x; /* prevent empty module */ #endif /* MathFncs */