home *** CD-ROM | disk | FTP | other *** search
- /* qexp.c */
- /* exponential function check routine */
-
- #include "qhead.h"
-
- extern short qlog2[], qone[];
-
- int qexp( x, y )
- short *x, *y;
- {
- short num[NQ], den[NQ], x2[NQ];
- long i;
- double f1;
- short sign;
-
- /* range reduction theory: x = i + f, 0<=f<1;
- * e**x = e**i * e**f
- * e**i = 2**(i/log 2).
- * Let i/log2 = i1 + f1, 0<=f1<1.
- * Then e**i = 2**i1 * 2**f1, so
- * e**x = 2**i1 * e**(log 2 * f1) * e**f.
- */
-
- if( x[1] <= 0 )
- {
- qmov( qone, y );
- return(0);
- }
- qmov(x, x2);
- sign = x2[0];
- if( sign < 0 )
- x2[0] = 0;
- qifrac( x2, &i, num ); /* x = i + f */
-
- if( i != 0 )
- {
- ltoq( &i, den ); /* floating point i */
- qdiv( qlog2, den, den ); /* i/log 2 */
- qifrac( den, &i, den ); /* i/log 2 = i1 + f1 */
- qmul( qlog2, den, den ); /* log 2 * f1 */
- qadd( den, num, x2 ); /* log 2 * f1 + f */
- }
-
- x2[1] -= 1; /* x/2 */
- qtanh( x2, x2 ); /* tanh( x/2 ) */
- qadd( x2, qone, num ); /* 1 + tanh */
- qneg( x2 );
- qadd( x2, qone, den ); /* 1 - tanh */
- qdiv( den, num, y ); /* (1 + tanh)/(1 - tanh) */
-
- y[1] += i;
- if( sign < 0 )
- qdiv( y, qone, y );
- }
-