move addtime() macro to the header file
[AROS.git] / workbench / libs / mathtrans / spatan.c
blobe50c411ab307e8a74e867d074e8ba6a3c05a5f75
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathtrans_intern.h"
8 /*****************************************************************************
10 NAME */
12 AROS_LH1(float, SPAtan,
14 /* SYNOPSIS */
15 AROS_LHA(float, fnum1, D0),
17 /* LOCATION */
18 struct Library *, MathTransBase, 5, MathTrans)
20 /* FUNCTION
21 Calculates the angle of a given number representing the tangent
22 of that angle. The angle will be in radians.
24 INPUTS
26 RESULT
27 Motorola fast floating point number
29 BUGS
31 INTERNALS
33 *****************************************************************************/
35 AROS_LIBFUNC_INIT
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));
43 /* atan(0) = 0 */
44 if (0 == fnumabs)
46 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
47 return 0;
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);
58 else
60 LONG res;
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 */
80 LONG res;
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);
85 return SPAdd
87 pio2, SPDiv
89 SPMul(three, fnumcubed),
90 SPAdd(res | FFPSign_Mask, one)
94 else
96 LONG res;
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);
101 res = SPAdd
103 pio2, SPDiv
105 SPMul(three, fnumcubed),
106 SPAdd( res | FFPSign_Mask, one )
109 return res | FFPSign_Mask;
113 /* atan(x <= 64) */
114 return SPAsin(SPDiv(SPSqrt(SPAdd(one,fnumsquared)),fnum1));
116 AROS_LIBFUNC_EXIT