2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include "mathieeedoubtrans_intern.h"
8 /*****************************************************************************
12 AROS_LHQUAD1(double, IEEEDPAtan
,
15 AROS_LHAQUAD(double, y
, D0
, D1
),
18 struct MathIeeeDoubTransBase
*, MathIeeeDoubTransBase
, 5, MathIeeeDoubTrans
)
21 Calculates the angle of a given number representing the tangent
22 of that angle. The angle will be in radians.
27 IEEE double precision floating point number
33 *****************************************************************************/
38 QUAD ysquared
, ycubed
, ypow5
, one
;
43 (IEEEDPMantisse_Mask_Hi
| IEEEDPExponent_Mask_Hi
),
44 (IEEEDPMantisse_Mask_Lo
| IEEEDPExponent_Mask_Lo
)
47 /* check for +- infinity -> output: +-pi/2 */
48 if (is_eqC(yabs
, IEEEDPPInfty_Hi
, IEEEDPPInfty_Lo
))
50 AND64QC(y
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
51 OR64QC(y
, pio2_hi_Hi
, pio2_hi_Lo
);
55 if (is_eqC(yabs
, 0, 0) /* 0 == yabs */ )
57 SetSR(Zero_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
61 ysquared
= IEEEDPMul(yabs
, yabs
);
62 ycubed
= IEEEDPMul(yabs
, ysquared
);
64 Set_Value64C(one
, one_Hi
, one_Lo
);
66 /* atan(x >= 860) = pi/2 - 1/x + 1/(3*x^3) */
67 if (Get_High32of64(yabs
) >= 0x408ae000)
70 Set_Value64C(tmp1
, pio2_hi_Hi
, pio2_hi_Lo
);
71 Set_Value64C(onethird
, onethird_Hi
, onethird_Lo
);
73 tmp1
= IEEEDPAdd(tmp1
,IEEEDPDiv(IEEEDPSub(onethird
, ysquared
),ycubed
));
75 if (is_eq(yabs
,y
)) /* arg has positive sign */
77 SetSR(0, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
82 SetSR(Negative_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
83 OR64QC(tmp1
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
89 atan(x >= 128) = pi/2 - 1/x + 1/(3*x^3) -1/(5*x^5)
90 = pi/2 + (1/3*x^2 - x^4 - 1/5) / x^5
92 if (Get_High32of64(yabs
) >= 0x40600000)
94 QUAD tmp1
, onethird
, onefifth
;
95 Set_Value64C(tmp1
, pio2_hi_Hi
, pio2_hi_Lo
);
96 Set_Value64C(onethird
, onethird_Hi
, onethird_Lo
);
97 Set_Value64C(onefifth
, onefifth_Hi
, onefifth_Lo
);
98 ypow5
= IEEEDPMul(ycubed
, ysquared
);
106 IEEEDPMul(onethird
,ysquared
),
107 IEEEDPMul(ysquared
,ysquared
)),onefifth
),ypow5
)
110 if (is_eq(yabs
,y
)) /* arg has positive sign */
112 SetSR(0, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
117 SetSR(Negative_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
118 OR64QC(tmp1
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
123 /* atan(x) = asin(x/sqrt(1+x^2)) */
125 return IEEEDPAsin(IEEEDPDiv(y
,IEEEDPSqrt(IEEEDPAdd(one
,ysquared
))));