/* DEC *AntiLog10Decimal(pDst,pSrc) * * ARGUMENT * pDst is a DEC pointer to the destination. * pSrc is a DEC pointer to the source. * * DESCRIPTION * Takes the base 10 anti-logarithm (power) of pSrc, * ie. 10**x, storing result in pDst. * * RETURNS * pDst if successful, GM_NULL otherwise. * * ALGORITHM * Set e**x = 10 ** y, then x*ln(e) = y*ln10. Then, ln(e)=1 by * definition, so x = y*ln(10), or y times a constant. Therefore, we * set z=y*ln(10), and 10**y = e**z. * * * POSSIBLE ERROR CODES * * GM_NULLPOINTER * GM_OVERFLOW * GM_UNDERFLOW * * AUTHOR * Andy Anderson 8-18-87 13:51 * Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved. * * MODIFICATIONS * */ #include #include "gm.h" #include "gmsystem.h" DEC *AntiLog10Decimal(pDst,pSrc) DEC *pDst; DEC *pSrc; { int i; DEC dtemp, *temp=&dtemp, *pt, t1; _MacStart(GM_DALOG); _MacInVar(pSrc,GM_NULL); _MacOutVar(pDst,GM_NULL); /* 10**0 is a one by definition */ if(_MacIsDecZ(pSrc)) { pt=&decOne; _MacDCopy(pDst,pt); _MacRet(pDst); } pt=&t1; _MacDZero(pt); /* if the power is integer and small enough, use int power rtn */ if((IsDecimalInt(pSrc)) && ((pSrc->dc.msd == 0) && (pSrc->ls.lsl[1] == 0L) && (pSrc->dc.sl[1] == 0)) && (!(pSrc->dc.sl[0] & 0x8000))) { pt->dc.id = 0; pt->dc.sl[0] = 10; i = _IntPwrDec80Bit(pt,pt,ConvDecimalToInt(pSrc)); if(i != GM_SUCCESS) { _MacErr(i); _MacRet(GM_NULL); } } else { /* first create z = y*ln10, overflow impossible */ (void) _MulDec80Bit(temp,pSrc,&decLn10); /* then e**(yln10) = 10**y */ i = _ExpDec80Bit(pt, temp); if(i==GM_OVERFLOW) { _MacErr(i); _MacRet(GM_NULL); } } i = _Sq5UnsTo4Uns(pt); /* reduce to 18-digit */ if(i!=GM_SUCCESS) { _MacErr(GM_OVERFLOW); _MacRet(GM_NULL); } if (_MacIsDecZ(pt)) { _MacErr(GM_UNDERFLOW); } _MacDCopy(pDst,pt); _MacRet(pDst); }