revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / mathieeesingtrans / ieeespatan.c
blob180f1b5c50dda2f9ca20b75e2c1f1c307f61de7b
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeesingtrans_intern.h"
8 /*****************************************************************************
10 NAME */
12 AROS_LH1(float, IEEESPAtan,
14 /* SYNOPSIS */
15 AROS_LHA(float, y, D0),
17 /* LOCATION */
18 struct Library *, MathIeeeSingTransBase, 5, MathIeeeSingTrans)
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 IEEE single precision floating point number
29 BUGS
31 INTERNALS
33 *****************************************************************************/
35 AROS_LIBFUNC_INIT
37 LONG yabs = y & (IEEESPMantisse_Mask | IEEESPExponent_Mask);
38 LONG ysquared, ycubed;
40 /* check for +- infinity -> output: +-pi/2 */
41 if (IEEESP_Pinfty == yabs) return (pio2 | (y & IEEESPSign_Mask));
43 /* atan(0) = 0 */
44 if (0 == yabs)
46 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
47 return 0;
50 /* atan(x >= 128) = pi/2 - 1/x */
51 if ( (yabs & IEEESPExponent_Mask) >= 0x43000000)
53 if (yabs == y) /* arg has ppositive sign */
55 SetSR(0, Zero_Bit | Negative_Bit | Overflow_Bit);
56 return IEEESPSub(pio2,IEEESPDiv(one,yabs));
58 else
60 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
61 return (IEEESPSub(pio2,IEEESPDiv(one,yabs))) | IEEESPSign_Mask;
65 /* atan(x >= 64) = pi/2 - 1/x +1/(3*x^3) */
67 ysquared = IEEESPMul(yabs, yabs);
69 if( (yabs & IEEESPExponent_Mask) >= 0x42000000)
71 ycubed = IEEESPMul(yabs, ysquared);
73 /* pi/2 - 1/x + 1/(3*x^3) = pi/2 + (1-3*x^2)/(3*x^3)*/
74 if (yabs == y) /* arg has positive sign */
76 SetSR(0, Zero_Bit | Negative_Bit | Overflow_Bit);
77 return IEEESPAdd
79 pio2, IEEESPDiv
81 IEEESPAdd
83 IEEESPMul(three, ysquared) | IEEESPSign_Mask, one
85 IEEESPMul(three, ycubed)
89 else
91 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
92 return IEEESPAdd
94 pio2, IEEESPDiv
96 IEEESPAdd
98 IEEESPMul(three, ysquared) | IEEESPSign_Mask, one
100 IEEESPMul(three, ycubed)
102 ) | IEEESPSign_Mask;
106 /* atan(x <= 64) */
107 return IEEESPAsin(IEEESPDiv(y,IEEESPSqrt(IEEESPAdd(one,ysquared))));
109 AROS_LIBFUNC_EXIT
110 } /* IEEESPAtan */