|
|
1.1 root 1: /* @(#)exp.c 4.1/4.2 09/24/85 CCI-CPG */
2:
3:
4: /*
5: * The double-precision 'exp' returns the exponential
6: * function of its floating-point argument.
7: *
8: * New version by Les Powers (3/23/85).
9: * Small operand fixed on (9/24/85).
10: */
11:
12:
13: #include <errno.h>
14:
15:
16:
17: /*
18: * The following number 'forces' the hex value of 0x7fffffff 0xffffffff
19: * to be used for HUGE.
20: */
21: #define HUGE 1.701411834604692350e+40
22:
23: #define EXPONENT28 0x0e000000
24: #define EXP_SIZE0 12
25: #define EXP_SIZE1 128
26: #define EXP_SIZE2 256
27: #define EXP_SIZE3 256
28: #define EXP_SIZE4 256
29:
30: int errno;
31:
32: /*
33: * This is the natural log of the smallest number that can
34: * be represented with double precision format (2^-128).
35: */
36: double _minf = -88.7228391116729996054057115466466007136640;
37:
38: /*
39: * This is the natural log of the biggest number that can
40: * be represented with double precision format (2^127 (1-2^-56)).
41: */
42: double _maxf = 88.0296919311130542821106916173739672939966;
43:
44: double _ep0[EXP_SIZE0];
45: double _ep1[EXP_SIZE1];
46: double _ep2[EXP_SIZE2];
47: double _ep3[EXP_SIZE3];
48: double _ep4[EXP_SIZE4];
49: double _en0[EXP_SIZE0];
50: double _en1[EXP_SIZE1];
51: double _en2[EXP_SIZE2];
52: double _en3[EXP_SIZE3];
53: double _en4[EXP_SIZE4];
54:
55:
56: double
57: exp(arg)
58: double arg;
59: {
60: int a0;
61: union {
62: int i;
63: struct {
64: unsigned char b0;
65: unsigned char b1;
66: unsigned char b2;
67: unsigned char b3;
68: } b;
69: } u;
70: register union {
71: double d;
72: int i;
73: } abs_arg;
74:
75: if (arg >= 0.0) {
76: abs_arg.d = arg;
77: if (abs_arg.i >= 0x42000000 ) { /* if (abs_arg.i >= 8.0) */
78: if (abs_arg.d > _maxf) {
79: errno = ERANGE;
80: return(HUGE);
81: }
82: a0 = abs_arg.d;
83: return(exp(arg - (a0&0x78)) * _ep0[a0>>3]);
84: }
85:
86: abs_arg.i += EXPONENT28; /* multiply by 2 to 28th power */
87: u.i = abs_arg.d;
88: abs_arg.d = u.i;
89: if ( abs_arg.i != 0 )
90: abs_arg.i -= EXPONENT28; /* divide by 2 to 28th power */
91: return(((arg-abs_arg.d)+1.)*
92: _ep1[u.b.b0]*_ep2[u.b.b1]*_ep3[u.b.b2]*_ep4[u.b.b3]);
93: } else {
94: abs_arg.d = -arg;
95: if (abs_arg.i >= 0x42000000) {
96: if (arg < _minf)
97: return(0.);
98: a0 = -arg;
99: return(exp(arg + (a0&0x78)) * _en0[a0>>3]);
100: }
101:
102: abs_arg.i += EXPONENT28; /* multiply by 2 to 28th power */
103: u.i = abs_arg.d;
104: abs_arg.d = u.i;
105: if ( abs_arg.i != 0 )
106: abs_arg.i -= EXPONENT28; /* divide by 2 to 28th power */
107: return(((arg+abs_arg.d)+1.)*
108: _en1[u.b.b0]*_en2[u.b.b1]*_en3[u.b.b2]*_en4[u.b.b3]);
109: }
110: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.