Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / mathtrans / spexp.c
blob05a1edf1babb1ecd07dc3fedb36442c4a0c96ede
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathtrans_intern.h"
8 /*
9 FUNCTION
10 Calculate e^x
12 RESULT
13 Motorola fast floating point number
15 flags:
16 zero : result is zero
17 negative : 0
18 overflow : the result was out of range for the ffp-format
20 NOTES
22 EXAMPLE
24 BUGS
26 SEE ALSO
28 INTERNALS
29 <code>
30 e^(>= 44): return FFP_Pinfty;
31 </code>
33 HISTORY
36 AROS_LH1(float, SPExp,
37 AROS_LHA(float, fnum1, D0),
38 struct Library *, MathTransBase, 13, MathTrans
41 AROS_LIBFUNC_INIT
43 const LONG ExpTable[] =
45 0x8fa1fe6f, /* e^32 */
46 0x87975e58, /* e^16 */
47 0xba4f534c, /* e^8 */
48 0xda648146, /* e^4 */
49 0xec732543, /* e^2 */
50 0xadf85442, /* e^1 */
51 0xD3094C41, /* e^(1/2) */
52 0xA45aF241, /* e^(1/4) */
53 0x910b0241, /* e^(1/8) */
54 0x88415b41, /* e^(1/16) */
55 0x84102b41, /* e^(1/32) */
56 0x82040541, /* e^(1/64) */
57 0x81010141, /* e^(1/128) */
58 0x80804041, /* e^(1/256) */
59 0x80401041, /* e^(1/512) */
60 0x80200441, /* e^(1/1024) */
61 0x80100141, /* e^(1/2048) */
62 0x80080041, /* e^(1/4096) */
63 0x80040041, /* e^(1/8192) */
64 0x80020041, /* e^(1/16384) */
65 0x80010041, /* e^(1/32768) */
66 0x80008041, /* e^(1/65536) */
67 0x80004041, /* e^(1/131072) */
68 0x80002041, /* e^(1/262144) */
69 0x80001041, /* e^(1/524288) */
70 0x80000841, /* e^(1/1048576) */
71 0x80000441, /* e^(1/2097152) */
72 0x80000241, /* e^(1/4194304) */
73 0x80000141 /* e^(1/8388608) */
76 ULONG Res, i;
77 LONG Mantisse;
78 char Exponent;
80 Exponent = (fnum1 & FFPExponent_Mask) - 0x41;
82 /* e^0 = 1, e^(2^(<=-24)) = 1 */
83 if ( 0 == fnum1 || Exponent <= -24 ) return one;
85 /* e^(>= 44) = overflow = infinity) */
86 if (Exponent > 5)
88 SetSR(Overflow_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
89 return FFP_Pinfty;
92 i = 5 - Exponent;
94 Mantisse = (fnum1 & FFPMantisse_Mask);
95 Res = ExpTable[i++];
96 Mantisse <<= 1;
98 while ( 0 != Mantisse && i <= 28 )
100 /* is the highest bit set? */
101 if ( Mantisse < 0 )
103 Res = SPMul(Res, ExpTable[i]);
104 if (0 == Res)
106 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
107 return Res;
109 if (FFP_Pinfty == Res)
111 SetSR(Overflow_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
112 return Res;
115 i++;
116 Mantisse <<= 1;
119 if ( (char) fnum1 < 0) return SPDiv(one, Res);
121 return Res;
123 AROS_LIBFUNC_EXIT