Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / mathieeedoubtrans / ieeedplog10.c
blob4c676f1cd10b19dbf49f4e27bac8a980a08bd794
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeedoubtrans_intern.h"
8 /*
9 FUNCTION
10 Calculate logarithm (base 10) of the given IEEE double precision number
12 RESULT
13 IEEE double precision 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 NAN.
32 If the Argument is 0 return 0xFFF0000000000000.
33 If the Argument is pos. Infinity return pos. Infinity.
35 All other cases:
37 (ld is the logarithm with base 2)
38 (log is the logarithm with base 10)
39 y = M * 2^E
41 log y = log ( M * 2^E ) =
43 = log M + log 2^E =
45 = log M + E * log (2) =
47 ld M ld 2
48 = ----- + E * ----- = [ld 2 = 1]
49 ld 10 ld 10
51 ld M + E
52 = --------
53 ld 10
55 ld 10 can be precalculated, of course.
56 For calculating ld M see file intern_ieeespld.c
58 HISTORY
61 AROS_LHQUAD1(double, IEEEDPLog10,
62 AROS_LHAQUAD(double, y, D0, D1),
63 struct MathIeeeDoubTransBase *, MathIeeeDoubTransBase, 21, MathIeeeDoubTrans
66 AROS_LIBFUNC_INIT
68 QUAD Res, tmp, Exponent64, ld_M;
69 LONG Exponent;
70 /* check for negative sign */
71 if ( is_lessSC(y, 0x0, 0x0) /* y<0 */)
73 SetSR(Overflow_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
74 Set_Value64C(Res, IEEEDPNAN_Hi, IEEEDPNAN_Lo);
75 return Res;
78 if ( is_eqC(y, 0x0, 0x0) )
80 Set_Value64C
82 Res,
83 (IEEEDPSign_Mask_Hi + IEEEDPExponent_Mask_Hi),
84 (IEEEDPSign_Mask_Lo + IEEEDPExponent_Mask_Lo)
86 return Res;
88 /* check for argument == 0 or argument == +infinity */
91 is_eqC(y, IEEEDPPInfty_Hi, IEEEDPPInfty_Lo)
92 || is_eqC(y, IEEEDPExponent_Mask_Hi, IEEEDPExponent_Mask_Lo)
95 return y;
98 /* convert the Exponent of the argument (y) to the ieeedp-format */
99 Exponent = ((Get_High32of64(y) & IEEEDPExponent_Mask_Hi) >> 20) - 0x3fe;
100 Exponent64 = IEEEDPFlt(Exponent);
102 Set_Value64(tmp, y);
103 AND64QC(tmp, IEEEDPMantisse_Mask_Hi, IEEEDPMantisse_Mask_Lo );
104 OR64QC(tmp, 0x3fe00000, 0x0);
105 ld_M = intern_IEEEDPLd
107 (struct MathIeeeDoubTransBase *) MathIeeeDoubTransBase, tmp
110 ld M + E
111 log(fnum1) = --------
112 ld 10
115 Set_Value64C(tmp, 0x3fd34413, 0x509f79ff ); /* 1/ld 10*/
116 return IEEEDPMul( IEEEDPAdd(ld_M, Exponent64), tmp);
118 AROS_LIBFUNC_EXIT