xref: /reactos/sdk/lib/crt/math/amd64/asin.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS CRT
4  * FILE:             lib/sdk/crt/math/amd64/asin.c
5  * PURPOSE:          Generic C implementation of arc sine
6  * PROGRAMMER:       Timo Kreuzer (timo.kreuzer@reactos.org)
7  */
8 
9 #define PRECISION 9
10 
11 /*
12  * The arc sine can be approximated with the following row:
13  *
14  *   asin(x) = a0*x + a1*x^3 + a2*x^5 + a3*x^7 + a4*x^9 + ...
15  *
16  * To reduce the number of multiplications the formula is transformed to
17  *
18  *   asin(x) = x * (1 + x^2*(a1 + x^2*(a2 + x^2*(a3 + ...) ) ) )
19  *
20  * The coefficients are:
21  *   a0 = 1
22  *   a1 = (1/2*3)
23  *   a2 = (3*1/4*2*5)
24  *   a3 = (5*3*1/6*4*2*7)
25  *   a4 = (7*5*3*1/8*6*4*2*9)
26  *   a5 = (9*7*5*3*1/10*8*6*4*2*11)
27  *   ...
28  */
29 
30 double
asin(double x)31 asin(double x)
32 {
33     double x2, result;
34 
35     /* Check range */
36     if ((x > 1.) || (x < -1.)) return NaN;
37 
38     /* Calculate the square of x */
39     x2 = (x * x);
40 
41     /* Start with 0, compiler will optimize this away */
42     result = 0;
43 
44     result += (15*13*11*9*7*5*3*1./(16*14*12*10*8*6*4*2*17));
45     result *= x2;
46 
47     result += (13*11*9*7*5*3*1./(14*12*10*8*6*4*2*15));
48     result *= x2;
49 
50     result += (11*9*7*5*3*1./(12*10*8*6*4*2*13));
51     result *= x2;
52 
53     result += (9*7*5*3*1./(10*8*6*4*2*11));
54     result *= x2;
55 
56     result += (7*5*3*1./(8*6*4*2*9));
57     result *= x2;
58 
59     result += (5*3*1./(6*4*2*7));
60     result *= x2;
61 
62     result += (3*1./(4*2*5));
63     result *= x2;
64 
65     result += (1./(2*3));
66     result *= x2;
67 
68     result += 1.;
69     result *= x;
70 
71     return result;
72 }
73 
74