6 // e = [2; 1, 2, 1, 1, 4, 1, ...]
7 static void *e_expansion(cf_t cf
) {
21 return cf_new_const(e_expansion
);
24 // 4/pi = 1 + 1/(3 + 4/(5 + 9/(7 + 16/(9 + ...))))
25 static void *pi_arctan_sequence(cf_t cf
) {
35 mpz_add_ui(denom
, denom
, 2);
37 mpz_add(num
, num
, denom
);
46 static void *regularized_pi(cf_t cf
) {
48 mpz_init(a
); mpz_init(b
); mpz_init(c
); mpz_init(d
);
49 mpz_set_ui(a
, 0); mpz_set_ui(b
, 4);
50 mpz_set_ui(c
, 1); mpz_set_ui(d
, 0);
51 cf_t nonregpi
= cf_new(pi_arctan_sequence
, NULL
);
52 cf_t conv
= cf_new_nonregular_to_cf(nonregpi
, a
, b
, c
, d
);
62 mpz_clear(a
); mpz_clear(b
); mpz_clear(c
); mpz_clear(d
);
67 return cf_new_const(regularized_pi
);
70 // tan 1 = [1; 1, 1, 3, 1, 5, ...]
71 static void *tan1_expansion(cf_t cf
) {
84 return cf_new_const(tan1_expansion
);
87 // exp(z) = 1 + z/(1 - z/(2 + z/(3 - z/(2 + z/(5 - z/(2 + z/ ...))))))
88 void *exp_expansion(cf_t cf
) {
89 mpz_ptr z
= cf_data(cf
);
92 mpz_init(odd
); mpz_init(two
); mpz_init(minusz
);
100 mpz_add_ui(odd
, odd
, 2);
104 mpz_clear(odd
); mpz_clear(two
); mpz_clear(minusz
);
110 // tanh n = z/(1 + z^2/(3 + z^2/(5 + z^2/...)))
111 static void *gauss_tanh_expansion(cf_t cf
) {
112 mpz_ptr z
= cf_data(cf
);
115 mpz_init(odd
); mpz_init(z2
);
123 mpz_add_ui(odd
, odd
, 2);
126 mpz_clear(odd
); mpz_clear(z2
);
132 // tan n = z/(1 - z^2/(3 - z^2/(5 - z^2/...)))
133 static void *gauss_tan_expansion(cf_t cf
) {
134 mpz_ptr z
= cf_data(cf
);
137 mpz_init(odd
); mpz_init(z2
);
146 mpz_add_ui(odd
, odd
, 2);
149 mpz_clear(odd
); mpz_clear(z2
);
155 cf_t
cf_new_one_arg(void *(*fun
)(cf_t
), mpz_t z
) {
156 mpz_ptr p
= malloc(sizeof(*p
));
159 return cf_new(fun
, p
);
166 typedef struct funarg_s
*funarg_ptr
;
168 static void *one_arg_nonreg(cf_t cf
) {
169 funarg_ptr p
= cf_data(cf
);
171 mpz_init(a
); mpz_init(b
); mpz_init(c
); mpz_init(d
);
172 mpz_set_ui(a
, 1); mpz_set_ui(b
, 0);
173 mpz_set_ui(c
, 0); mpz_set_ui(d
, 1);
174 mpz_ptr copy
= malloc(sizeof(*copy
));
176 mpz_set(copy
, p
->arg
);
177 cf_t nonreg
= cf_new(p
->fun
, copy
);
178 cf_t conv
= cf_new_nonregular_to_cf(nonreg
, a
, b
, c
, d
);
188 mpz_clear(a
); mpz_clear(b
); mpz_clear(c
); mpz_clear(d
);
195 cf_t
cf_new_one_arg_nonreg(void *(*fun
)(cf_t
), mpz_t z
) {
196 funarg_ptr p
= malloc(sizeof(*p
));
200 return cf_new(one_arg_nonreg
, p
);
203 cf_t
cf_new_epow(mpz_t pow
) {
204 return cf_new_one_arg_nonreg(exp_expansion
, pow
);
207 cf_t
cf_new_tanh(mpz_t z
) {
208 return cf_new_one_arg_nonreg(gauss_tanh_expansion
, z
);
211 // TODO: Handle negative convergents so this function works.
212 cf_t
cf_new_tan(mpz_t z
) {
213 return cf_new_one_arg_nonreg(gauss_tanh_expansion
, z
);