Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / mathieeedoubtrans / ieeedppow.c
blob1572b352992fb634e9b1b49b638a28156654a50e
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeedoubtrans_intern.h"
8 /*
9 FUNCTION
10 Calculate y raised to the x power (y^x)
12 RESULT
13 IEEE double precision floating point number
15 flags:
16 zero : result is zero
17 negative : result is negative
18 overflow : result is too big
20 NOTES
22 EXAMPLE
24 BUGS
26 SEE ALSO
28 INTERNALS
30 HISTORY
33 AROS_LHQUAD2(double, IEEEDPPow,
34 AROS_LHAQUAD(double, x, D2, D3),
35 AROS_LHAQUAD(double, y, D0, D1),
36 struct MathIeeeDoubTransBase *, MathIeeeDoubTransBase, 15, MathIeeeDoubTrans
39 AROS_LIBFUNC_INIT
41 /*
42 a ^ b = e^(b * ln a)
43 y ^ x = e^(x * ln y)
45 QUAD Res, tmp;
47 /* y^x is illegal if y<0 and x is not an integer-value */
48 if (is_lessSC(y, 0x0, 0x0) && is_neq(x, IEEEDPCeil(x)))
50 Set_Value64C(Res, 0x0, 0x0);
51 return Res;
54 if (is_eqC(y, 0x0, 0x0))
56 Set_Value64C(Res, 0x3ff00000, 0x0);
57 return Res;
59 Set_Value64(tmp, y);
60 AND64QC
62 tmp,
63 (IEEEDPMantisse_Mask_Hi + IEEEDPExponent_Mask_Hi),
64 (IEEEDPMantisse_Mask_Lo + IEEEDPExponent_Mask_Lo)
67 Res = IEEEDPLog(tmp);
68 Res = IEEEDPMul(Res, x);
69 Res = IEEEDPExp(Res);
71 /*
72 if y < 0 and x was and even integer, the result is positive, otherwise
73 it is negative.
77 is_lessSC(y, 0x0, 0x0)
78 && TRUE == intern_IEEEDPisodd(x)
81 OR64QC(Res, IEEEDPSign_Mask_Hi, IEEEDPSign_Mask_Lo);
84 if (is_eqC(Res, 0x0, 0x0))
86 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
87 Set_Value64C(Res, 0x0, 0x0);
88 return Res;
91 SetSR(0, Zero_Bit | Negative_Bit | Overflow_Bit);
93 if (is_lessSC(Res, 0x0, 0x0))
95 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
98 Set_Value64(tmp, Res);
99 AND64QC
101 tmp,
102 (IEEEDPMantisse_Mask_Hi + IEEEDPExponent_Mask_Hi),
103 (IEEEDPMantisse_Mask_Lo + IEEEDPExponent_Mask_Lo)
106 if (is_eqC(Res, IEEEDPPInfty_Hi, IEEEDPPInfty_Lo))
108 /* don`t touch the Negative_Bit now!*/
109 SetSR(Overflow_Bit, Zero_Bit | Overflow_Bit);
112 return Res;
114 AROS_LIBFUNC_EXIT