Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / mathtrans / spatan.c
blob3d0a429ada452d6fad4e402e489f5153806c105a
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathtrans_intern.h"
8 /*
9 FUNCTION
10 Calculates the angle of a given number representing the tangent
11 of that angle. The angle will be in radians.
13 RESULT
14 Motorola fast floating point number
16 NOTES
18 EXAMPLE
20 BUGS
22 SEE ALSO
24 INTERNALS
26 HISTORY
29 AROS_LH1(float, SPAtan,
30 AROS_LHA(float, fnum1, D0),
31 struct Library *, MathTransBase, 5, MathTrans
34 AROS_LIBFUNC_INIT
36 LONG fnumabs = fnum1 & (FFPMantisse_Mask | FFPExponent_Mask);
37 LONG fnumsquared, fnumcubed;
39 /* check for +- infinity -> output: +-pi/2 */
40 if ((LONG)FFP_Pinfty == fnumabs ) return (pio2 | (fnum1 & FFPSign_Mask));
42 /* atan(0) = 0 */
43 if (0 == fnumabs)
45 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
46 return 0;
49 /* atan(x>= 128) = pi/2 - 1/x */
50 if ((BYTE) fnumabs >= 0x48)
52 if (fnumabs == fnum1) /* arg has ppositive sign */
54 SetSR(0, Zero_Bit | Negative_Bit | Overflow_Bit);
55 return SPSub(SPDiv(fnumabs,one),pio2);
57 else
59 LONG res;
60 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
62 /* workaround a bug in egcs 1.0.3: complains about illegal operands to | */
63 res = SPSub(SPDiv(fnumabs,one),pio2);
64 return res | FFPSign_Mask;
68 /* atan(x >= 64) = pi/2 - 1/x +1/(3*x^3) */
70 fnumsquared = SPMul(fnumabs, fnumabs);
72 if((BYTE) fnumabs >= 0x47)
74 fnumcubed = SPMul(fnumabs, fnumsquared);
76 /* pi/2 - 1/x + 1/(3*x^3) = pi/2 + (1-3*x^2)/(3*x^3)*/
77 if (fnumabs == fnum1) /* arg has positive sign */
79 LONG res;
80 SetSR(0, Zero_Bit | Negative_Bit | Overflow_Bit);
82 /* workaround a bug in egcs 1.0.3: complains about illegal operands to | */
83 res = SPMul(three, fnumsquared);
84 return SPAdd
86 pio2, SPDiv
88 SPMul(three, fnumcubed),
89 SPAdd(res | FFPSign_Mask, one)
93 else
95 LONG res;
96 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
98 /* workaround a bug in egcs 1.0.3: complains about illegal operands to | */
99 res = SPMul(three, fnumsquared);
100 res = SPAdd
102 pio2, SPDiv
104 SPMul(three, fnumcubed),
105 SPAdd( res | FFPSign_Mask, one )
108 return res | FFPSign_Mask;
112 /* atan(x <= 64) */
113 return SPAsin(SPDiv(SPSqrt(SPAdd(one,fnumsquared)),fnum1));
115 AROS_LIBFUNC_EXIT