So we have two requirements:
Use at most 5 multiplications.
Errror is no more than 10%.
Requirement 2 means that we want to optimize (minimze) the relative error of the approximation.
Requiring 5 multiplications + 3 additions
I'll interpret requirement 1) such that divisions are not wanted because they are usually (much) more expensive than multiplictatios.
In order to minimize the relative error, we'll have to "get rid" of the zero of $\arcsin(x)$ at $x=0$. We achieve this by approximating $\arcsin(x) / x$. Also we want to take advantage of the symmetry of $\arcsin$. Thus, we approximate
$$
f(x) = \frac{\arcsin \sqrt x}{\sqrt x} \quad\text{ over }\quad [0,1]\tag 1
$$
which has no zeros, and then use
$$
\arcsin x = x\cdot f(x^2) \tag2
$$
Equation (2) costs 2 multiplications, thus we have 3 multiplications left to approximate $f$ by a polynomial of degree 3. Remez algorithm yields
$$
f(x) = 0.9678828 + 0.8698691 x - 2.166373 x^2 + 1.848968 x^3
$$
with a relative error bounded by 0.033 which is well below the 10% margin. As the relative error of $f(x)$ is the same like the relative error of $xf(x^2)$, we are done. A C-ish implementation would read:
// Approximate arcsin(x) with a relative error better than 0.033.
// Costs = 5 multiplications, 3 additions.
double approx_asin (double x)
{
double a0 = +0.9678828;
double a1 = +0.8698691;
double a2 = -2.166373;
double a3 = +1.848968;
double q = x * x;
return x * (a0 + q * (a1 + q * (a2 + q * a3)));
}
which costs 5 multiplications and 3 additions. Here is a plot of the relative error of $f(x)$:
Requiring 3 multiplications + 1 addition
Now $\arcsin$ has singularities at $\pm1$ which means that polynomial approximations won't converge well as the polynomial degree increases. The other way round, we don't lose much of the accuracy when we decrease the polynomial degree, and indeed a polynomial of degree 1 has a relative error of below 0.084 which is better that the required 10%:
// Approximate arcsin(x) with a relative error better than 0.084.
// Costs = 3 multiplications, 1 addition.
double approx_asin (double x)
{
double q = x * x;
return x * (0.916735 + 0.523269 * q);
}
The relative error of $f(x)$ looks like:
Finally, here is a Desmos plot of the two approximations. It shows $\arcsin$ in black, the approximations (dotted) and the relative errors (multiplied by 10 for display): In red the relative error for the degree-3-approximaton, and in green for the degree-1-approximaton.
Approximating arcsin and arccos to IEEE single precision
In order to achieve IEEE single precision, using polynomials or rational functions alone won't work well due to the singularities (branch points) at $\pm1$. As $\cos x\approx 1-x^2/2$ near $x=0$, we have $\arccos x\approx \sqrt{2-2x}$ near $x=1$. Doing the math, we find that
$$
\arccos x = \sqrt{2-2x}\,a(1-x)
$$
where $a(x)$ is analytic at $x=0$ with radius of convergence of $2$. Actually, it's
$$
a(x) = \frac{\arcsin \sqrt{x/2}}{\sqrt{x/2}} = 1 + \frac1{12}x+\frac3{160}x^2+{\mathcal O}(x^3)
$$
It's not advisable to approximate $a(x)$ over all of $[0,2]$ (or over $[0,1]$ for that matter). Instead, we approximate $a(x)$ over $[0,1/2]$ and do a piece-wise approximation:
- If $|x| \leqslant 1/2$, compute $A_x = x\cdot a(2x^2)$.
- If $|x| > 1/2$, compute $C_x = \sqrt{2z}\cdot a(z)$ where $z=1-|x|$.
Then use:
$$\begin{align}
\arcsin x &= \begin{cases}
A_x &;\text{ if } |x|\leqslant 1/2 \\
(\pi/2-C_x)\operatorname{sign}(x) &;\text{ if } |x|> 1/2 \\
\end{cases} \\
\\
\arccos x &= \begin{cases}
C_x &;\text{ if } x> 1/2 \\
\pi/2-A_x &;\text{ if } |x|\leqslant 1/2 \\
\pi-C_x &;\text{ if } x<-1/2 \\
\end{cases}
\end{align}$$
where we approximate $a(x)$ by a MiniMax rational function of degree [2/2]:
$$
a(x)\approx\frac
{45.210185257899 - 18.617417552712 x + x^2}
{45.210185141956 - 22.384922725383 x + 2.0175735681637 x^2}
{}
$$
This approximates $\arccos$ with a relative error of less than 2.6·10−9 (which is better than 28.5 bits).
And it approximates $\arcsin$ with a relative error of less than 5·10−9 (which is better than 27.5 bits).
If one division costs more than 2 multiplications and 1 addition, then it's more efficient to approximate $a(x)$ by a polynomial of degree 5 with coefficients
a0 = 0.99999999552357
a1 = 0.08333395776062
a2 = 0.018735953473147
a3 = 0.0056946210646921
a4 = 0.0014889678470141
a5 = 0.0013342813628708
evaluated using Horner's method. The resulting precision is around one bit less than with using the [2/2] rational approximation for $a$.