2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include "mathtrans_intern.h"
8 /*****************************************************************************
12 AROS_LH1(float, SPAtan
,
15 AROS_LHA(float, fnum1
, D0
),
18 struct Library
*, MathTransBase
, 5, MathTrans
)
21 Calculates the angle of a given number representing the tangent
22 of that angle. The angle will be in radians.
27 Motorola fast floating point number
33 *****************************************************************************/
37 LONG fnumabs
= fnum1
& (FFPMantisse_Mask
| FFPExponent_Mask
);
38 LONG fnumsquared
, fnumcubed
;
40 /* check for +- infinity -> output: +-pi/2 */
41 if ((LONG
)FFP_Pinfty
== fnumabs
) return (pio2
| (fnum1
& FFPSign_Mask
));
46 SetSR(Zero_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
50 /* atan(x>= 128) = pi/2 - 1/x */
51 if ((BYTE
) fnumabs
>= 0x48)
53 if (fnumabs
== fnum1
) /* arg has ppositive sign */
55 SetSR(0, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
56 return SPSub(SPDiv(fnumabs
,one
),pio2
);
61 SetSR(Negative_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
63 /* workaround a bug in egcs 1.0.3: complains about illegal operands to | */
64 res
= SPSub(SPDiv(fnumabs
,one
),pio2
);
65 return res
| FFPSign_Mask
;
69 /* atan(x >= 64) = pi/2 - 1/x +1/(3*x^3) */
71 fnumsquared
= SPMul(fnumabs
, fnumabs
);
73 if((BYTE
) fnumabs
>= 0x47)
75 fnumcubed
= SPMul(fnumabs
, fnumsquared
);
77 /* pi/2 - 1/x + 1/(3*x^3) = pi/2 + (1-3*x^2)/(3*x^3)*/
78 if (fnumabs
== fnum1
) /* arg has positive sign */
81 SetSR(0, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
83 /* workaround a bug in egcs 1.0.3: complains about illegal operands to | */
84 res
= SPMul(three
, fnumsquared
);
89 SPMul(three
, fnumcubed
),
90 SPAdd(res
| FFPSign_Mask
, one
)
97 SetSR(Negative_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
99 /* workaround a bug in egcs 1.0.3: complains about illegal operands to | */
100 res
= SPMul(three
, fnumsquared
);
105 SPMul(three
, fnumcubed
),
106 SPAdd( res
| FFPSign_Mask
, one
)
109 return res
| FFPSign_Mask
;
114 return SPAsin(SPDiv(SPSqrt(SPAdd(one
,fnumsquared
)),fnum1
));