/* DEC *PowerRational(pDst,pSrc1,m,n) * * ARGUMENT * DEC *pDst,*pSrc1; * int m,n; * * DESCRIPTION * Calculates pSrc1 to the power m/n and returns the answer in pDst. * This provides an x**(m/n) power function for DEC numbers. * * SIDE EFFECTS * None. * * RETURNS * Pointer to the result if no error, otherwise GM_NULL. * * ALGORITHM: * x**(m/n) = e**((m/n)*ln(x)). Therefore, call dlnx() to get the * natural log * and then multiply by the power of x. Finally, call dexx() to provide * e**z. * * POSSIBLE ERROR CODES * * GM_NULLPOINTER * GM_OVERFLOW * GM_UNDERFLOW * GM_IMAG * GM_PWR0 * GM_DIV0 * * AUTHOR * Andy Anderson 05-JAN-1987 17:30 * Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved. * * MODIFICATIONS * */ #include #include "gm.h" #include "gmsystem.h" DEC *PowerRational(pDst,pSrc,m,n) DEC *pDst, *pSrc; int m,n; { DEC temp, *pt, *nsrc, dnsrc, ddm, *dm=&ddm; int i, isn=0; _MacStart(GM_DPOWRAT); _MacInVarD(pSrc); _MacOutVarD(pDst); if (n == 0) { _MacErr(GM_DIV0); _MacRet(GM_NULL); } if (_MacIsDecZ(pSrc)) { if (!((m<0)^(n<0))&&(m!=0)) { _MacDZero(pDst); _MacRet(pDst); } else { _MacErr(GM_PWR0); _MacRet(GM_NULL); } } if (m == 0) { _MacDCopy(pDst,&decOne); _MacRet(pDst); } if (_MacIsDecN(pSrc)) { while ((m % 2) + (n % 2) == 0) { m=m/2; n=n/2; } if ((n % 2) == 0) { _MacErr(GM_IMAG); _MacRet(GM_NULL); } isn=m % 2; nsrc = &dnsrc; _MacDCopy(nsrc,pSrc); pSrc=nsrc; _MacDChgs(nsrc); } pt = &temp; (void) _LnDec80Bit(pt, pSrc); (void) ConvLongToDecimal(dm, (long) m); (void) _MulDec80Bit(pt, pt, dm); (void) ConvLongToDecimal(dm, (long) n); (void) _DivDec80Bit(pt, pt, dm); i = _ExpDec80Bit(pt, pt); if(i==GM_OVERFLOW) { _MacErr(i); _MacRet(GM_NULL); } i = _Sq5UnsTo4Uns(pt); if(i!=GM_SUCCESS) { _MacErr(GM_OVERFLOW); _MacRet(GM_NULL); } if (_MacIsDecZ(pt)) { _MacErr(GM_UNDERFLOW); } if (isn) _MacDChgs(pt); _MacDCopy(pDst,pt); _MacRet(pDst); }