2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include "mathieeedoubtrans_intern.h"
10 Calculates the angle of a given number representing the tangent
11 of that angle. The angle will be in radians.
14 IEEE double precision floating point number
29 AROS_LHQUAD1(double, IEEEDPAtan
,
30 AROS_LHAQUAD(double, y
, D0
, D1
),
31 struct MathIeeeDoubTransBase
*, MathIeeeDoubTransBase
, 5, MathIeeeDoubTrans
37 QUAD ysquared
, ycubed
, ypow5
, one
;
42 (IEEEDPMantisse_Mask_Hi
| IEEEDPExponent_Mask_Hi
),
43 (IEEEDPMantisse_Mask_Lo
| IEEEDPExponent_Mask_Lo
)
46 /* check for +- infinity -> output: +-pi/2 */
47 if (is_eqC(yabs
, IEEEDPPInfty_Hi
, IEEEDPPInfty_Lo
))
49 AND64QC(y
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
50 OR64QC(y
, pio2_hi_Hi
, pio2_hi_Lo
);
54 if (is_eqC(yabs
, 0, 0) /* 0 == yabs */ )
56 SetSR(Zero_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
60 ysquared
= IEEEDPMul(yabs
, yabs
);
61 ycubed
= IEEEDPMul(yabs
, ysquared
);
63 Set_Value64C(one
, one_Hi
, one_Lo
);
65 /* atan(x >= 860) = pi/2 - 1/x + 1/(3*x^3) */
66 if (Get_High32of64(yabs
) >= 0x408ae000)
69 Set_Value64C(tmp1
, pio2_hi_Hi
, pio2_hi_Lo
);
70 Set_Value64C(onethird
, onethird_Hi
, onethird_Lo
);
72 tmp1
= IEEEDPAdd(tmp1
,IEEEDPDiv(IEEEDPSub(onethird
, ysquared
),ycubed
));
74 if (is_eq(yabs
,y
)) /* arg has positive sign */
76 SetSR(0, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
81 SetSR(Negative_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
82 OR64QC(tmp1
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
88 atan(x >= 128) = pi/2 - 1/x + 1/(3*x^3) -1/(5*x^5)
89 = pi/2 + (1/3*x^2 - x^4 - 1/5) / x^5
91 if (Get_High32of64(yabs
) >= 0x40600000)
93 QUAD tmp1
, onethird
, onefifth
;
94 Set_Value64C(tmp1
, pio2_hi_Hi
, pio2_hi_Lo
);
95 Set_Value64C(onethird
, onethird_Hi
, onethird_Lo
);
96 Set_Value64C(onefifth
, onefifth_Hi
, onefifth_Lo
);
97 ypow5
= IEEEDPMul(ycubed
, ysquared
);
105 IEEEDPMul(onethird
,ysquared
),
106 IEEEDPMul(ysquared
,ysquared
)),onefifth
),ypow5
)
109 if (is_eq(yabs
,y
)) /* arg has positive sign */
111 SetSR(0, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
116 SetSR(Negative_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
117 OR64QC(tmp1
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
122 /* atan(x) = asin(x/sqrt(1+x^2)) */
124 return IEEEDPAsin(IEEEDPDiv(y
,IEEEDPSqrt(IEEEDPAdd(one
,ysquared
))));