2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 * Developed at SunSoft, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
13 * ====================================================
16 #include "mathtrans_intern.h"
20 Calculate arcussin of the given number
23 Motorola fast floating point number
27 negative : result is negative
28 overflow : fnum < -1 or fnum > 1
43 AROS_LH1(float, SPAsin
,
44 AROS_LHA(float, fnum1
, D0
),
45 struct Library
*, MathTransBase
, 19, MathTrans
51 LONG t
,w
,p
,q
,c
,r
,s
,ix
;
52 ix
= fnum1
& (FFPMantisse_Mask
| FFPExponent_Mask
); /* ix = |fnum| */
54 if ((LONG
)one
== ix
) /* |fnum1| = 1 -> result = +-(pi/2) */
56 return (pio2
| (fnum1
& FFPSign_Mask
));
59 if (1 == SPCmp(ix
,one
)) /* |fnum1| > 1 */
61 SetSR(Overflow_Bit
, Zero_Bit
| Overflow_Bit
| Negative_Bit
);
65 /* error: 1 ulp (unit in the last place)*/
66 if (-1 == SPCmp(ix
,onehalf
)) /* |fnum1| < 0.5 */
68 if (-1 == SPCmp(ix
,0xb89b6736)) /* |fnum1| < 70422/10000000 */
73 t
= SPMul(fnum1
, fnum1
);
74 p
= SPMul(t
, SPAdd(pS0
,
79 SPMul(t
, pS5
)))))))))));
87 return SPAdd(fnum1
, SPMul(fnum1
, w
));
91 w
= SPSub(ix
, one
) ; /* w = 1 - fnum ; y = 1-x */
92 t
= SPMul(w
, onehalf
); /* t = w / 2 ; z = y/2 */
93 p
= SPMul(t
,SPAdd(pS0
,
98 SPMul(t
,pS5
)))))))))));
104 s
= SPSqrt(t
); /* s = sqrt(t) ; s = sqrt(z) */
106 if(1 == SPCmp(ix
, 0xf9999a40 /*0.975*/ )) /* |fnum| > 0.975 */
108 /*error: 2 ulp (4 ulp when |fnum| close to 1) */
109 w
= SPDiv(q
,p
); /* w = p / q; */
110 /* res = pi/2-(2*(s+s*w)) */
111 t
= SPSub(SPMul(two
,SPAdd(s
,SPMul(s
,w
))),pio2
);
112 t
= SPAdd(t
, 0x8000002b); /* for better accuracy */
118 c
= SPDiv(SPAdd(s
,w
),SPSub(SPMul(w
,w
),t
)); /* c=(t-w*w)/(s+w) */
120 p
= SPAdd(SPAdd(c
,c
),SPMul(SPAdd(s
,s
),r
));
121 q
= SPSub(SPAdd(w
,w
) ,pio4
);
122 t
= SPSub(SPSub(q
,p
) ,pio4
);
125 return (t
| (fnum1
& FFPSign_Mask
)) ;