Listtree.mcc: implement proxying of DisplayHook
[AROS.git] / workbench / libs / mathieeedoubtrans / ieeedplog10.c
blob7526db2b36c55bed38747dd3d0ecbb071ea47ee4
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeedoubtrans_intern.h"
8 /*****************************************************************************
10 NAME */
12 AROS_LHQUAD1(double, IEEEDPLog10,
14 /* SYNOPSIS */
15 AROS_LHAQUAD(double, y, D0, D1),
17 /* LOCATION */
18 struct MathIeeeDoubTransBase *, MathIeeeDoubTransBase, 21, MathIeeeDoubTrans)
20 /* FUNCTION
21 Calculate logarithm (base 10) of the given IEEE double precision number
23 INPUTS
25 RESULT
26 IEEE double 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 NAN.
39 If the Argument is 0 return 0xFFF0000000000000.
40 If the Argument is pos. Infinity return pos. Infinity.
42 All other cases:
44 (ld is the logarithm with base 2)
45 (log is the logarithm with base 10)
46 y = M * 2^E
48 log y = log ( M * 2^E ) =
50 = log M + log 2^E =
52 = log M + E * log (2) =
54 ld M ld 2
55 = ----- + E * ----- = [ld 2 = 1]
56 ld 10 ld 10
58 ld M + E
59 = --------
60 ld 10
62 ld 10 can be precalculated, of course.
63 For calculating ld M see file intern_ieeespld.c
65 *****************************************************************************/
67 AROS_LIBFUNC_INIT
69 QUAD Res, tmp, Exponent64, ld_M;
70 LONG Exponent;
71 /* check for negative sign */
72 if ( is_lessSC(y, 0x0, 0x0) /* y<0 */)
74 SetSR(Overflow_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
75 Set_Value64C(Res, IEEEDPNAN_Hi, IEEEDPNAN_Lo);
76 return Res;
79 if ( is_eqC(y, 0x0, 0x0) )
81 Set_Value64C
83 Res,
84 (IEEEDPSign_Mask_Hi + IEEEDPExponent_Mask_Hi),
85 (IEEEDPSign_Mask_Lo + IEEEDPExponent_Mask_Lo)
87 return Res;
89 /* check for argument == 0 or argument == +infinity */
92 is_eqC(y, IEEEDPPInfty_Hi, IEEEDPPInfty_Lo)
93 || is_eqC(y, IEEEDPExponent_Mask_Hi, IEEEDPExponent_Mask_Lo)
96 return y;
99 /* convert the Exponent of the argument (y) to the ieeedp-format */
100 Exponent = ((Get_High32of64(y) & IEEEDPExponent_Mask_Hi) >> 20) - 0x3fe;
101 Exponent64 = IEEEDPFlt(Exponent);
103 Set_Value64(tmp, y);
104 AND64QC(tmp, IEEEDPMantisse_Mask_Hi, IEEEDPMantisse_Mask_Lo );
105 OR64QC(tmp, 0x3fe00000, 0x0);
106 ld_M = intern_IEEEDPLd
108 (struct MathIeeeDoubTransBase *) MathIeeeDoubTransBase, tmp
111 ld M + E
112 log(fnum1) = --------
113 ld 10
116 Set_Value64C(tmp, 0x3fd34413, 0x509f79ff ); /* 1/ld 10*/
117 return IEEEDPMul( IEEEDPAdd(ld_M, Exponent64), tmp);
119 AROS_LIBFUNC_EXIT