/* * Program to see how numerically accurate the infinite series for sin * and cos are. * * e^x = 1 + x + x^2/2! + x^3/3! + x^4/4! + x^5/5! + ... * * e^ix = 1 + i x - x^2/2! - i x^3/3! + x^4/4! + i x^5/5! + ... * = cos x + i sin x * -> * cos x = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! + ... * sin x = x - x^3/3! + x^5/5! - x^7/7! + x^9/9! + ... * * We truncate them at the point at which the next term does not change * the computer-represented value. This is in principle dangerous for * infinite series in general, but in this case it's safe - at that * point, the terms' absolute value is declining fast. * * We use integers and half-integers up to 6, then two pi, since the * nature of these series is such that larger arguments need more * terms to achieve a given level of accuracy. For each argument, * output looks like * * arg [ sin(arg) cos(arg) ] * sin-so-far cos-so-far * sin-so-far cos-so-far * ... * sin-so-far cos-so-far * -> sin-error cos-error * * After all these, a single line with the maximum power of x used, * across all functions and all arguments. */ #include #include static int maxn; static void try(double a) { double rs; double rc; double s; double c; double ps; double pc; double ap; int n; rs = sin(a); rc = cos(a); s = a; c = 1; n = 1; ap = a; printf("%g [ %g %g ]\n",a,rs,rc); do { ps = s; pc = c; printf("%g %g\n",s,c); n ++; ap *= a / n; if (n & 2) c -= ap; else c += ap; n ++; ap *= a / n; if (n & 2) s -= ap; else s += ap; } while ((s != ps) || (c != pc)); printf(" -> %g %g\n",rs-s,rc-c); if (n > maxn) maxn = n; } int main(void); int main(void) { maxn = 0; try(0); try(.5); try(1); try(1.5); try(2); try(2.5); try(3); try(3.5); try(4); try(4.5); try(5); try(5.5); try(6); try(3.1415926535897932384626433*2); printf("%d\n",maxn); return(0); }