Files correlati : Ricompilazione Demo : [ ] Commento : Aggiunti i sorgenti per Greenleaf Math Library (gfm.dll) git-svn-id: svn://10.65.10.50/trunk@10079 c028cbd2-c16b-5b4b-a496-9718f37d4682
114 lines
2.2 KiB
C
Executable File
114 lines
2.2 KiB
C
Executable File
/* int _ExpDec80Bit(pDst,pSrc)
|
|
*
|
|
* ARGUMENT
|
|
* DEC *pDst, *pSrc;
|
|
*
|
|
* DESCRIPTION
|
|
* Calculates e^pSrc, stores result in pDst.
|
|
*
|
|
* SIDE EFFECTS
|
|
* None.
|
|
*
|
|
* RETURNS
|
|
* GM_SUCCESS if calculation is successful,
|
|
* otherwise the error code (which could be underflow)
|
|
*
|
|
* ALGORITHM
|
|
* pSrc = a * ln 2 + b |b| < (ln 2) / 2
|
|
* e^pSrc = (2^a) * (e^b)
|
|
* Using the Taylor series,
|
|
* e^b = 1 + b + (b^2)/2! + (b^3)/3! + ...
|
|
*
|
|
* AUTHOR
|
|
* Jared Levy April 7, 1987
|
|
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
|
|
*
|
|
* MODIFICATIONS
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "gm.h"
|
|
#include "gmsystem.h"
|
|
|
|
int _ExpDec80Bit(pDst,pSrc)
|
|
DEC *pDst, *pSrc;
|
|
{
|
|
int a, i;
|
|
DEC da, dpow2, db, dt, dfact, dterm;
|
|
DEC *pow2, *b, *fact, *pt, *term;
|
|
|
|
if (CompareDecimal(pSrc,&decMaxExp) == 1) {
|
|
return(GM_OVERFLOW);
|
|
}
|
|
|
|
if (CompareDecimal(pSrc,&decMinExp) == -1) {
|
|
_MacDZero(pDst);
|
|
return(GM_UNDERFLOW);
|
|
}
|
|
|
|
/* calculate a = pSrc * (1/(ln 2)) */
|
|
(void) _MulDec80Bit(&da, pSrc, &decReciprocalOfLn2);
|
|
|
|
(void) _ScaleDec80Bit(&da,&da,0);
|
|
a = ConvDecimalToInt(&da);
|
|
|
|
/* calculate b = pSrc - a * ln 2 */
|
|
b=&db;
|
|
if (a == 0) {
|
|
_MacDCopy(b,pSrc);
|
|
}
|
|
else {
|
|
(void) _MulDec80Bit(&dt, &da, &decLn2);
|
|
(void) _SubDec80Bit(b, pSrc, &dt);
|
|
}
|
|
|
|
/* calculate pSrc = (2^a) * (e^b) */
|
|
fact = &dfact;
|
|
pt = &decOne;
|
|
term = &dterm;
|
|
_MacDCopy(fact,pt);
|
|
_MacDCopy(pDst,pt);
|
|
_AddDec80Bit(pDst, pDst, b);
|
|
_MacDCopy(term, b);
|
|
|
|
do {
|
|
/* calulate next term */
|
|
fact->dc.sl[0]++;
|
|
(void) _MulDec80Bit(term, b, term);
|
|
(void) _DivRndDec80Bit(term, term, fact, 23);
|
|
/* add term to series */
|
|
(void) _AddDec80Bit(pDst, pDst, term);
|
|
/* calc next factorial term in divisor */
|
|
} while (!(_MacIsDecZ(term)));
|
|
|
|
if (a>0) {
|
|
pow2 = &dpow2;
|
|
/*
|
|
* I used to use the _MacDZero statement here, but Lattice C 6.0
|
|
* pointed out that it had a single redundant line in the
|
|
* macro, so I expanded it and remove the redundant line.
|
|
* _MacDZero(pow2);
|
|
*/
|
|
pow2->dc.attr=0;
|
|
pow2->ls.lsl[0]=0;
|
|
pow2->ls.lsl[1]=0;
|
|
pow2->dc.msd=0;
|
|
|
|
pow2->dc.id = 0;
|
|
pow2->dc.sl[a/16] = 1 << (a % 16);
|
|
i =_MulDec80Bit(pDst, pDst, pow2);
|
|
return(i);
|
|
}
|
|
|
|
while (a<0) {
|
|
_HalveUnsArr(pDst->dc.sl, 5);
|
|
a++;
|
|
}
|
|
|
|
if (_MacIsDecZ(pDst))
|
|
return(GM_UNDERFLOW);
|
|
|
|
return(GM_SUCCESS);
|
|
}
|