Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / mathtrans / splog.c
blobf378747b655c79ec71ce31e779ba7d2a8147b0ca
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathtrans_intern.h"
8 /*
9 FUNCTION
10 Calculate logarithm (base e) of the given ffp number
12 RESULT
13 ffp-number
15 flags:
16 zero : result is zero
17 negative : result is negative
18 overflow : argument was negative
20 NOTES
22 EXAMPLE
24 BUGS
26 SEE ALSO
28 INTERNALS
29 ALGORITHM:
31 If the Argument is negative set overflow-flag and return 0.
32 If the Argument is 0 return 0xffffffff.
34 All other cases:
36 (ld is the logarithm with base 2)
37 (ln is the logarithm with base e)
38 <code>
39 fnum1 = M * 2^E
41 ln fnum1 = ln ( M * 2^E ) =
43 = ln M + ln 2^E =
45 = ln M + E * ln (2) =
47 ld M ld 2
48 = ----- + E * ----- = [ld 2 = 1]
49 ld e ld e
51 ld M + E
52 = --------
53 ld e
54 </code>
56 ld e can be precalculated, of course.
57 For calculating ld M see file intern_spld.c
59 HISTORY
62 AROS_LH1(float, SPLog,
63 AROS_LHA(float, fnum1, D0),
64 struct Library *, MathTransBase, 14, MathTrans
67 AROS_LIBFUNC_INIT
69 LONG ld_M, Exponent, Mask = 0x40, i, Sign;
71 /* check for negative sign */
72 if ((char) fnum1 < 0)
74 SetSR(Overflow_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
75 return 0;
78 /* check for argument == 0 -> return (-infinity) */
79 if (fnum1 == 0) return FFP_Ninfty;
81 /* convert the Exponent of the argument (fnum1) to the ffp-format */
82 Exponent = (fnum1 & FFPExponent_Mask) - 0x40;
83 if (Exponent < 0 )
85 Exponent =-Exponent;
86 Sign = FFPSign_Mask;
88 else
90 Sign = 0;
93 /* find the number of the highest set bit in the exponent */
94 if (Exponent != 0)
96 i = 0;
97 while ( (Mask & Exponent) == 0)
99 i ++;
100 Mask >>= 1;
102 Exponent <<= (25 + i);
103 Exponent |= (0x47 - i + Sign);
106 ld_M = intern_SPLd((fnum1 & FFPMantisse_Mask) | 0x40);
108 /* ld M + E
109 ** ln(fnum1) = --------
110 ** ld e
113 return SPMul( SPAdd(ld_M, Exponent), InvLde);
115 AROS_LIBFUNC_EXIT