revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / mathieeesingtrans / ieeesplog10.c
blobc96866742aedaf1a0855981be91cc77fb0b169e4
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeesingtrans_intern.h"
8 /*****************************************************************************
10 NAME */
12 AROS_LH1(float, IEEESPLog10,
14 /* SYNOPSIS */
15 AROS_LHA(float, y, D0),
17 /* LOCATION */
18 struct Library *, MathIeeeSingTransBase, 21, MathIeeeSingTrans)
20 /* FUNCTION
21 Calculate logarithm (base 10) of the given IEEE single precision number
23 INPUTS
25 RESULT
26 IEEE single precision number
28 flags:
29 zero : result is zero
30 negative : result is negative
31 overflow : argument was negative
33 BUGS
35 INTERNALS
36 ALGORITHM:
38 If the Argument is negative set overflow-flag and return 0.
39 If the Argument is 0 return 0xffffffff.
41 All other cases:
43 (ld is the logarithm with base 2)
44 (log is the logarithm with base 10)
45 y = M * 2^E
47 log y = log ( M * 2^E ) =
49 = log M + log 2^E =
51 = log M + E * log (2) =
53 ld M ld 2
54 = ----- + E * ----- = [ld 2 = 1]
55 ld 10 ld 10
57 ld M + E
58 = --------
59 ld 10
61 ld 10 can be precalculated, of course.
62 For calculating ld M see file intern_ieeespld.c
64 *****************************************************************************/
66 AROS_LIBFUNC_INIT
68 LONG ld_M, Exponent, Mask = 0x40, i, Sign;
70 /* check for negative sign */
71 if ( y < 0)
73 SetSR(Overflow_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
74 return 0;
77 /* check for argument == 0 or argument == +infinity */
78 if (0 == y || IEEESP_Pinfty == y) return y;
80 /* convert the Exponent of the argument (y) to the ieeesp-format */
81 Exponent = ((y & IEEESPExponent_Mask) >> 23) - 0x7e ;
83 if (Exponent < 0 )
85 Exponent =-Exponent;
86 Sign = IEEESPSign_Mask;
88 else
90 Sign = 0;
92 /* find the number of the highest set bit in the exponent */
93 if (Exponent != 0)
95 i = 0;
96 while ( (Mask & Exponent) == 0)
98 i ++;
99 Mask >>= 1;
102 Exponent <<= (17 + i);
103 Exponent &= IEEESPMantisse_Mask;
104 Exponent |= ((0x85 - i ) << 23);
105 Exponent |= Sign;
108 ld_M = intern_IEEESPLd((y & IEEESPMantisse_Mask) | 0x3f000000);
111 ld M + E
112 log(fnum1) = --------
113 ld 10
116 return IEEESPMul( IEEESPAdd(ld_M, Exponent), InvLd10);
118 AROS_LIBFUNC_EXIT