PLEASE NOTE: In this case, I strongly recommend the @Bence method, since you cannot expect a slow converged method with low data accuracy to get arbitrary accuracy.
However, I am ready to show you how to improve the result using your current algorithm.
The main problem is that a and b grow too fast and soon become inf (after about 150 iterations). Another similar problem: my_pow(xp,n) grows rapidly when n grows, but in this case it does not really matter, since we can assume that the input data falls into the range [-1, 1] .
So, I just changed the method you work with a/b by typing ab_ratio , see my edited code:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define EPS 0.000000000001 #include <math.h> #define my_pow powl #define my_abs fabsl double my_arcsin(double x) { #if 0 long double a, an, b, bn; a = an = 1.0; b = bn = 2.0; #endif unsigned long _n = 0; long double ab_ratio = 0.5; long double n = 3.0; long double xn; long double xs = x; long double xp = x; int iterace = 0; xn = xs + ab_ratio * (my_pow(xp,n) / n); long double step = EPS; #if 0 while (my_abs(step) >= EPS) #else while (1) /* manually stop it */ #endif { n += 2.0; #if 0 an += 2.0; bn += 2.0; a = a * an; b = b * bn; #endif _n += 1; ab_ratio *= (1.0 + 2.0 * _n) / (2.0 + 2.0 * _n); xs = xn; step = ab_ratio * (my_pow(xp,n) / n); xn = xs + step; iterace++; if (_n % 10000000 == 0) printf("%lu %.10g %g %g %g %g\n", _n, (double)xn, (double)ab_ratio, (double)step, (double)xn, (double)my_pow(xp, n)); } //printf("%d\n", iterace); return xn; } int main(int argc, char* argv[]) { double x = 0.0; if (argc > 2) x = strtod(argv[2], NULL); if (strcmp(argv[1], "--asin") == 0) { if (x < -1 || x > 1) printf("nan\n"); else { printf("%.10e\n", my_arcsin(x)); //printf("%.10e\n", asin(x)); } return 0; } }
For 0.99 (and even 0.9999999 ), he will soon give the correct results with more than 10 significant digits. However, it is approaching 1 . Actually, the process runs for almost 12 minutes on my laptop, calculating --asin 1 , and the current result is 1.570786871 after 3560000000 iterations.
UPDATED: Now it was 1h51min, and the result was 1.570792915 and the iteration counter was 27340000000 .