grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / libs / mathieeedoubtrans / ieeedppow.c
blob01f522dfe2ad2ee4851f158a54407ad7819e356c
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeedoubtrans_intern.h"
8 /*****************************************************************************
10 NAME */
12 AROS_LHQUAD2(double, IEEEDPPow,
14 /* SYNOPSIS */
15 AROS_LHAQUAD(double, x, D2, D3),
16 AROS_LHAQUAD(double, y, D0, D1),
18 /* LOCATION */
19 struct MathIeeeDoubTransBase *, MathIeeeDoubTransBase, 15, MathIeeeDoubTrans)
21 /* FUNCTION
22 Calculate y raised to the x power (y^x)
24 INPUTS
26 RESULT
27 IEEE double precision floating point number
29 flags:
30 zero : result is zero
31 negative : result is negative
32 overflow : result is too big
34 BUGS
36 INTERNALS
38 *****************************************************************************/
40 AROS_LIBFUNC_INIT
42 /*
43 a ^ b = e^(b * ln a)
44 y ^ x = e^(x * ln y)
46 QUAD Res, tmp;
48 /* y^x is illegal if y<0 and x is not an integer-value */
49 if (is_lessSC(y, 0x0, 0x0) && is_neq(x, IEEEDPCeil(x)))
51 Set_Value64C(Res, 0x0, 0x0);
52 return Res;
55 if (is_eqC(y, 0x0, 0x0))
57 Set_Value64C(Res, 0x3ff00000, 0x0);
58 return Res;
60 Set_Value64(tmp, y);
61 AND64QC
63 tmp,
64 (IEEEDPMantisse_Mask_Hi + IEEEDPExponent_Mask_Hi),
65 (IEEEDPMantisse_Mask_Lo + IEEEDPExponent_Mask_Lo)
68 Res = IEEEDPLog(tmp);
69 Res = IEEEDPMul(Res, x);
70 Res = IEEEDPExp(Res);
72 /*
73 if y < 0 and x was and even integer, the result is positive, otherwise
74 it is negative.
78 is_lessSC(y, 0x0, 0x0)
79 && TRUE == intern_IEEEDPisodd(x)
82 OR64QC(Res, IEEEDPSign_Mask_Hi, IEEEDPSign_Mask_Lo);
85 if (is_eqC(Res, 0x0, 0x0))
87 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
88 Set_Value64C(Res, 0x0, 0x0);
89 return Res;
92 SetSR(0, Zero_Bit | Negative_Bit | Overflow_Bit);
94 if (is_lessSC(Res, 0x0, 0x0))
96 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
99 Set_Value64(tmp, Res);
100 AND64QC
102 tmp,
103 (IEEEDPMantisse_Mask_Hi + IEEEDPExponent_Mask_Hi),
104 (IEEEDPMantisse_Mask_Lo + IEEEDPExponent_Mask_Lo)
107 if (is_eqC(Res, IEEEDPPInfty_Hi, IEEEDPPInfty_Lo))
109 /* don`t touch the Negative_Bit now!*/
110 SetSR(Overflow_Bit, Zero_Bit | Overflow_Bit);
113 return Res;
115 AROS_LIBFUNC_EXIT