campo-sirio/gfm/dexx.c
alex ba237a9d91 Patch level : no patch
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
2002-02-26 12:19:02 +00:00

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);
}