|
|
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.