Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / mathtrans / spacos.c
blobd6b9efa7c3513274a5f2629a7351d701ee00f348
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
10 * Developed at SunSoft, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
17 #include "mathtrans_intern.h"
20 FUNCTION
21 Calculate arcuscos of the given number
23 RESULT
24 Motorola fast floating point number
26 flags:
27 zero : result is zero
28 negative : 0 (not possible)
29 overflow : fnum < -1 or fnum > 1
31 NOTES
33 EXAMPLE
35 BUGS
37 SEE ALSO
39 INTERNALS
41 HISTORY
44 AROS_LH1(float, SPAcos,
45 AROS_LHA(float, fnum1, D0),
46 struct Library *, MathTransBase, 20, MathTrans
49 AROS_LIBFUNC_INIT
51 /* 1> |x| >= 0.5 */
52 LONG z,p,q,r,w,s,c,ix,df;
53 ix = fnum1 & (FFPMantisse_Mask | FFPExponent_Mask); /* ix = |fnum| */
55 z = SPCmp(ix,one);
57 if (1==z) /* |fnum1| > 1 */
59 SetSR(Overflow_Bit, Zero_Bit | Overflow_Bit | Negative_Bit);
60 return -1;
63 if (0==z) /* |fnum1| = 1 */
65 if (fnum1 & FFPSign_Mask) /* |fnum| = -1 */ return pi;
66 SetSR(Zero_Bit, Zero_Bit | Overflow_Bit | Negative_Bit);
67 return 0;
70 /* error: 1 ulp (unit in the last place) */
71 if (-1 == SPCmp(ix,onehalf)) /* |fnum1| < 0.5 */
73 z = SPMul(fnum1, fnum1);
74 p = SPMul(z, SPAdd(pS0,
75 SPMul(z, SPAdd(pS1,
76 SPMul(z, SPAdd(pS2,
77 SPMul(z, SPAdd(pS3,
78 SPMul(z, SPAdd(pS4,
79 SPMul(z, pS5)))))))))));
80 q = SPAdd(one,
81 SPMul(z, SPAdd(qS1,
82 SPMul(z, SPAdd(qS2,
83 SPMul(z, SPAdd(qS3,
84 SPMul(z, qS4))))))));
85 r = SPDiv(q, p);
86 return (SPSub(SPAdd(fnum1,SPMul(fnum1,r)),pio2));
89 /* error: 1 ulp */
90 if (fnum1 & FFPSign_Mask) /* fnum1 < -0.5 */
92 z = SPMul(onehalf, SPAdd(one, fnum1));
93 p = SPMul(z, SPAdd(pS0,
94 SPMul(z, SPAdd(pS1,
95 SPMul(z, SPAdd(pS2,
96 SPMul(z, SPAdd(pS3,
97 SPMul(z, SPAdd(pS4,
98 SPMul(z, pS5)))))))))));
99 q = SPAdd(one,
100 SPMul(z, SPAdd(qS1,
101 SPMul(z, SPAdd(qS2,
102 SPMul(z, SPAdd(qS3,
103 SPMul(z, qS4))))))));
104 s = SPSqrt(z);
105 r = SPDiv(q,p); /* r = p/q; */
106 w = SPMul(r,s);
107 return SPSub(SPMul(two, SPAdd(s, w)) ,pi);
110 /* error: 8 ulp (this is bad !!!!) */
111 /* fnum1 > 0.5 */
112 z = SPMul(onehalf, SPSub(fnum1, one));
113 s = SPSqrt(z);
114 df = s;
115 df = df & 0xfff000ff;
116 c = SPDiv(SPAdd(df,s), SPSub( SPMul(df,df), z));
117 p = SPMul(z, SPAdd(pS0,
118 SPMul(z, SPAdd(pS1,
119 SPMul(z, SPAdd(pS2,
120 SPMul(z, SPAdd(pS3,
121 SPMul(z, SPAdd(pS4,
122 SPMul(z, pS5)))))))))));
123 q = SPAdd(one,
124 SPMul(z, SPAdd(qS1,
125 SPMul(z, SPAdd(qS2,
126 SPMul(z, SPAdd(qS3,
127 SPMul(z, qS4))))))));
128 r = SPDiv(q, p);
129 w = SPAdd(c, SPMul(r,s));
131 return SPAdd(SPMul(two, SPAdd(df,w)),0x800000a9);
133 AROS_LIBFUNC_EXIT