home *** CD-ROM | disk | FTP | other *** search
-
- /*
-
- Math library for LightspeedC
-
- (C) Copyright 1986 THINK Technologies. All rights reserved.
-
- For details, refer to Harbison & Steele's "C: A Reference Manual",
- Chapter 11.
-
- Two versions of each function are defined by this library: an
- error-checking version (e.g. "sin") and a non-error-checking
- version (e.g. "_sin").
-
- The non-underscore names can be made to refer to the non-error-
- checking functions by #defining _NOERRORCHECK_ before #including
- "math.h". Doing so in THIS file suppresses the definitions of
- the error-checking versions of the functions altogether.
-
- */
-
- /*#define _NOERRORCHECK_*/
- #include "Math.h"
-
- /* useful constants */
- static double Zero = 0.0;
- static double One = 1.0;
- static double MinusOne = -1.0;
- static double Pi = PI;
- static double Pi2 = PI2;
-
-
- /* seed for pseudo-random number generator */
- static unsigned long seed = 1;
-
- #ifdef _ERRORCHECK_
-
- extern int errno; /* defined in stdio */
-
- #define EDOM 33
- #define ERANGE 34
-
- #define ERROR 0x0000FF00 /* 68881 mask to check for exceptions */
-
- /* GetState() and ClearExceptions() are in Math881.a */
- /*
- GetState returns the entire 68881 Floating-Point Status Register (FPSR);
- ClearExceptions ANDs the FPSR with $00FF0000 to clear all but the quotient
- byte.
- */
-
- long GetState();
- void ClearExceptions();
-
- #define DomainCheck(test, result) if (test) { \
- errno = EDOM; \
- return(result); \
- }
-
- #define RangeCheck(target) if (GetState() & ERROR) { \
- errno = ERANGE; \
- target = Max; \
- }
-
- static short _Max[] = { 0x7FFE, 0x0000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF };
- static short _MinusMax[] = { 0xFFFE, 0x0000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF };
- #define Max (* (double *) _Max)
- #define MinusMax (* (double *) _MinusMax)
-
- #else
- #define DomainCheck(test, result)
- #define RangeCheck(value)
- #endif
-
- /*
- the functions rand, srand, and xfersign
- get defined regardless of whether there's error checking or not.
- */
-
- /* rand - pseudo-random number generator (ANSI C standard) */
-
- int rand()
- {
- seed = seed * 1103515245 + 12345;
- asm {
- move.w seed,d0 ; high word of long
- andi.w #0x7FFF,d0 ; remove high bit
- }
- }
-
-
- /* srand - seed pseudo-random number generator */
-
- void srand(n)
- unsigned n;
- {
- seed = n;
- }
-
- /* xfersign - transfer sign from one floating number to another */
-
- static
- xfersign(x, yp)
- double x, *yp;
- {
- asm {
- movea.l yp,a0
- bclr #7,(a0)
- tst.w x
- bpl.s @1
- bset #7,(a0)
- @1 }
- }
-
-
- #ifdef _ERRORCHECK_
-
- /* ---------- math functions (alphabetically) ---------- */
-
-
- /*
- * acos - inverse circular cosine
- *
- */
-
- double acos(x)
- register double x;
- {
- DomainCheck(x > One || x < MinusOne, Zero);
- if (x == MinusOne)
- return(Pi);
- return(_acos(x));
- }
-
-
- /*
- * asin - inverse circular sine
- *
- */
-
- double asin(x)
- register double x;
- {
- double y = fabs(x);
-
- DomainCheck(y > One, Zero);
- return(_asin(x));
- }
-
-
- /*
- * atan - inverse circular tangent - defined as macro in Math881.h
- *
- */
- double atan(x)
- register double x;
- {
- return(_atan(x));
- }
-
- double atan2(y, x)
- register double y, x;
- {
- return(_atan2(y, x));
- }
-
- /*
- * ceil - round up to an integer
- *
- */
-
- double ceil(x)
- register double x;
- {
- return(_ceil(x));
- }
-
-
- /*
- * cos - circular cosine
- *
- */
-
- double cos(x)
- register double x;
- {
- return(_cos(x));
- }
-
-
- /*
- * cosh - hyperbolic cosine
- *
- */
-
- double cosh(x)
- register double x;
- {
- ClearExceptions();
- x = _cosh(x);
- RangeCheck(x);
- return(x);
- }
-
-
- /*
- * exp - exponential function
- *
- */
-
- double exp(x)
- register double x;
- {
- ClearExceptions();
- x = _exp(x);
- RangeCheck(x);
- return(x);
- }
-
-
- /*
- * fabs - absolute value of a floating number
- *
- */
-
- double fabs(x)
- register double x;
- {
- return(_fabs(x));
- }
-
-
- /*
- * floor - round down to an integer
- *
- */
-
- double floor(x)
- register double x;
- {
- return(_floor(x));
- }
-
-
- /*
- * fmod - remainder function
- *
- * This computes a value z, with the same sign as x, such that for some
- * integer k, k*y + z == x.
- *
- */
-
- double fmod(x, y)
- register double x, y;
- {
- return(_fmod(x, y));
- }
-
-
- /*
- * frexp - split floating number into fraction/exponent
- *
- * This computes a value z, where 0.5 <= fabs(z) < 1.0, and an integer n such
- * that z*(2^n) == x.
- *
- */
-
- double frexp(x, nptr)
- register double x;
- register int *nptr;
- {
- return(_frexp(x, nptr));
- }
-
-
- /*
- * ldexp - combine fraction/exponent into a floating number
- *
- */
-
- double ldexp(x, n)
- register double x;
- register int n;
- {
- return(_ldexp(x, n));
- }
-
-
- /*
- * log - natural logarithm
- *
- */
-
- double log(x)
- register double x;
- {
- DomainCheck(x <= 0, MinusMax);
- return(_log(x));
- }
-
-
- /*
- * log10 - logarithm base 10
- *
- */
-
- double log10(x)
- register double x;
- {
- DomainCheck(x <= 0, MinusMax);
- return(_log10(x));
- }
-
-
- /*
- * modf - split a floating number into fraction/integer
- *
- */
-
- double modf(x, nptr)
- double x, *nptr;
- {
- return(_modf(x, nptr));
- }
-
-
- /* pow - power function (exponentiation) */
-
- double pow(x, y)
- register double x, y;
- {
- return(_pow(x, y)); /* _pow() does the proper error checking. */
- }
-
-
- /*
- * sin - circular sine
- *
- */
-
- double sin(x)
- register double x;
- {
- return(_sin(x));
- }
-
-
- /*
- * sinh - hyperbolic sine
- *
- */
-
- double sinh(x)
- register double x;
- {
- register double y;
-
- ClearExceptions();
- y = _sinh(x);
- RangeCheck(y);
- return(y);
- }
-
-
- /*
- * sqrt - square root
- *
- */
-
- double sqrt(x)
- register double x;
- {
- DomainCheck(x < 0, Zero);
- return(_sqrt(x));
- }
-
-
- /*
- * tan - circular tangent
- *
- */
-
- double tan(x)
- register double x;
- {
- ClearExceptions();
- x = _tan(x);
- RangeCheck(x);
- return(x);
- }
-
-
- /*
- * tanh - hyperbolic tangent
- *
- */
-
- double tanh(x)
- double x;
- {
- return(_tanh(x));
- }
-
- #endif _ERRORCHECK_
-
-