/* DEC *TangentDecimal(pDst,pSrc) * * ARGUMENT * DEC *pDst; * DEC *pSrc; * * DESCRIPTION * Sets pDst = the tangent of pSrc radians. * * SIDE EFFECTS * Possible Errors: GM_NULLPOINTER, * GM_OVERFLOW if | tan(pSrc) | > 2^63 * * RETURNS * Returns pointer to pDst if successful, otherwise a GM_NULL. * * POSSIBLE ERROR CODES * * GM_NULLPOINTER * GM_OVERFLOW * * AUTHOR * Jared Levy Oct 16, 1987 * Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved. * * ALGORITHM * tan(x) = +/- (1 - cos(x) ^ 2 ) ^ .5 / cos(x) * * MODIFICATIONS * */ #include #include "gm.h" #include "gmsystem.h" DEC *TangentDecimal(pDst,pSrc) DEC *pDst; DEC *pSrc; { int i, isn=0; DEC *nsrc, dnsrc, *size, dsize, *temp, dtemp; DEC *cosx, dcosx, *sinx, dsinx; _MacStart(GM_DTAN); _MacInVarD(pSrc); _MacOutVarD(pDst); nsrc = &dnsrc; _MacDCopy(nsrc, pSrc); if (_MacIsDecN(nsrc)) { isn = 1; _MacDChgs(nsrc); } temp = &dtemp; if (CompareDecimal(nsrc, &decPiOver2) == 1) { (void) _DivRndDec80Bit(size = &dsize, nsrc, &decPi, 0); (void) _MulDec80Bit(temp, &decPi, size); (void) _SubDec80Bit(nsrc, nsrc, temp); if (_MacIsDecN(nsrc)) { isn = 1 - isn; _MacDChgs(nsrc); } } _CosDec80Bit(cosx = &dcosx, nsrc); if (_MacIsDecZ(cosx)) { _MacErr(GM_OVERFLOW); _MacRet(GM_NULL); } (void) _MulDec80Bit(temp, cosx, cosx); (void) _SubDec80Bit(temp, &decOne, temp); _SqrtDec80Bit(sinx = &dsinx, temp); i = _DivDec80Bit(pDst, sinx, cosx); if (i == GM_OVERFLOW) { _MacErr(GM_OVERFLOW); _MacRet(GM_NULL); } i = _Sq5UnsTo4Uns(pDst); if (i != GM_SUCCESS) { _MacErr(GM_OVERFLOW); _MacRet(GM_NULL); } if (isn) _MacDChgs(pDst); _MacRet(pDst); }