21a20fa6eaf8a6e576e8e5cb7a535bc8f2fd7749
6 // sin 1 from Taylor series
7 static void *sin1_expansion(cf_t cf
) {
11 mpz_init(r
); mpz_init(s
);
16 for (i
= 1; i
<= k
; i
++ ) {
17 mpz_mul_ui(s
, s
, (2 * i
) * (2 * i
+ 1));
18 mpz_mul_ui(r
, r
, (2 * i
) * (2 * i
+ 1));
28 // Compute limit = (2k + 1)! / 2
29 mpz_mul_ui(limit
, s
, k
);
30 mpz_mul_ui(limit
, s
, 2 * k
+ 1);
34 mpz_init(p0
); mpz_init(p1
);
35 mpz_init(q0
); mpz_init(q1
);
40 mpz_init(a
); mpz_init(b
);
42 mpz_init(t0
); mpz_init(t1
);
49 // Pump out start of expansion.
52 mpz_fdiv_qr(t0
, t1
, a
, b
);
55 mpz_addmul(q0
, q1
, t0
);
57 if (mpz_cmp(a
, limit
) >= 0) {
61 mpz_addmul(p0
, p1
, t0
);
65 // gmp_printf("%Zd (%Zd) -> %Zd / %Zd\n", t0, t1, p1, q1);
67 // if (!mpz_sgn(t1)) die("sin(1) is rational!\n");
74 mpz_mul_ui(limit
, limit
, 2 * k
);
75 mpz_mul_ui(limit
, limit
, 2 * k
+ 1);
76 mpz_mul_ui(s
, s
, (2 * k
) * (2 * k
+ 1));
77 mpz_mul_ui(r
, r
, (2 * k
) * (2 * k
+ 1));
83 gmp_printf("r/s = %Zd/%Zd\n", r
, s
);
85 void increase_limit() {
87 // Last output was for a lower bound.
88 // We need an upper bound of sin 1.
90 if (k
& 1) increase_k();
93 // Last output was for an upper bound.
95 // We need a lower bound of sin 1.
97 if (!(k
& 1)) increase_k();
105 // Find largest x such that (p1 x + p0)/(q1 x + q0) R r/s
106 // where R is < for even i, and > for odd i
107 // i.e. (p1 s - q1 r)x R q0 r - p0 s
114 mpz_fdiv_q(t0
, a
, b
);
116 // Then x is the next convergent provided it is within limits.
118 mpz_addmul(q0
, q1
, t0
);
120 gmp_printf("%Zd > %Zd?\n", a
, limit
);
121 if (mpz_cmp(a
, limit
) >= 0) {
126 gmp_printf("term: %Zd\n", t0
);
129 mpz_addmul(p0
, p1
, t0
);
138 int main(int argc
, char *argv
[]) {
139 cf_t x
= cf_new_const(sin1_expansion
);
140 cf_t conv
= cf_new_convergent(x
);
143 for (int i
= 0; i
< 10; i
++) {
144 cf_get(z
, conv
); gmp_printf("%d: %Zd/", i
, z
);
145 cf_get(z
, conv
); gmp_printf("%Zd\n", z
);