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"
18 /*****************************************************************************
22 AROS_LH1(float, SPAsin
,
25 AROS_LHA(float, fnum1
, D0
),
28 struct Library
*, MathTransBase
, 19, MathTrans
)
31 Calculate arcussin of the given number
36 Motorola fast floating point number
40 negative : result is negative
41 overflow : fnum < -1 or fnum > 1
47 *****************************************************************************/
52 LONG t
,w
,p
,q
,c
,r
,s
,ix
;
53 ix
= fnum1
& (FFPMantisse_Mask
| FFPExponent_Mask
); /* ix = |fnum| */
55 if ((LONG
)one
== ix
) /* |fnum1| = 1 -> result = +-(pi/2) */
57 return (pio2
| (fnum1
& FFPSign_Mask
));
60 if (1 == SPCmp(ix
,one
)) /* |fnum1| > 1 */
62 SetSR(Overflow_Bit
, Zero_Bit
| Overflow_Bit
| Negative_Bit
);
66 /* error: 1 ulp (unit in the last place)*/
67 if (-1 == SPCmp(ix
,onehalf
)) /* |fnum1| < 0.5 */
69 if (-1 == SPCmp(ix
,0xb89b6736)) /* |fnum1| < 70422/10000000 */
74 t
= SPMul(fnum1
, fnum1
);
75 p
= SPMul(t
, SPAdd(pS0
,
80 SPMul(t
, pS5
)))))))))));
88 return SPAdd(fnum1
, SPMul(fnum1
, w
));
92 w
= SPSub(ix
, one
) ; /* w = 1 - fnum ; y = 1-x */
93 t
= SPMul(w
, onehalf
); /* t = w / 2 ; z = y/2 */
94 p
= SPMul(t
,SPAdd(pS0
,
99 SPMul(t
,pS5
)))))))))));
105 s
= SPSqrt(t
); /* s = sqrt(t) ; s = sqrt(z) */
107 if(1 == SPCmp(ix
, 0xf9999a40 /*0.975*/ )) /* |fnum| > 0.975 */
109 /*error: 2 ulp (4 ulp when |fnum| close to 1) */
110 w
= SPDiv(q
,p
); /* w = p / q; */
111 /* res = pi/2-(2*(s+s*w)) */
112 t
= SPSub(SPMul(two
,SPAdd(s
,SPMul(s
,w
))),pio2
);
113 t
= SPAdd(t
, 0x8000002b); /* for better accuracy */
119 c
= SPDiv(SPAdd(s
,w
),SPSub(SPMul(w
,w
),t
)); /* c=(t-w*w)/(s+w) */
121 p
= SPAdd(SPAdd(c
,c
),SPMul(SPAdd(s
,s
),r
));
122 q
= SPSub(SPAdd(w
,w
) ,pio4
);
123 t
= SPSub(SPSub(q
,p
) ,pio4
);
126 return (t
| (fnum1
& FFPSign_Mask
)) ;