-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtest_pell.c
75 lines (69 loc) · 1.83 KB
/
test_pell.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "pell.h"
#include "rootmod.h"
#include "coultau.h"
#include "gmp_main.h"
mpz_t zA;
mpz_t zD;
int in;
mpz_t zlimit;
mpz_t zx;
mpz_t zy;
/* needed for coultau.c; but not used, since we init_tau(0, 0) */
#include "coul.h"
t_divisors *divisors = NULL;
void fail(char *format, ...) {
va_list ap;
va_start(ap, format);
gmp_vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(1);
}
void ston(mpz_t targ, char *s) {
char *t = strchr(s, 'e');
if (t) {
*t = 0;
mpz_set_str(targ, s, 10);
ulong exp = strtoul(&t[1], NULL, 10);
mpz_t temp;
mpz_init(temp);
mpz_ui_pow_ui(temp, 10, exp);
mpz_mul(targ, targ, temp);
mpz_clear(temp);
*t = 'e';
} else {
mpz_set_str(targ, s, 10);
}
}
/* Run this with 4 arguments (A, D, N, lim) to test the Pell solver.
* We will search for solutions to Ax^2 - Dy^2 = N with 0 <= x <= lim.
* A, D, lim are each positive integers, of arbitrary size;
* N is a signed int, so must typically fit in 32 bits.
* lim can be given in exponential format (without decimal), eg "1e20".
*/
int main(int argc, char **argv) {
if (argc < 5)
fail("Usage: %s <A> <D> <N> <lim> to solve Ax^2 - Dy^2 = N\n", argv[0]);
mpz_init_set_str(zA, argv[1], 10);
mpz_init_set_str(zD, argv[2], 10);
in = strtol(argv[3], NULL, 10);
mpz_init(zlimit);
ston(zlimit, argv[4]);
gmp_printf("try new_pell(%Zu, %Zu, %d, %Zu)\n", zA, zD, in, zlimit);
mpz_init(zx);
mpz_init(zy);
_GMP_init();
init_tau(0, 0);
init_rootmod(1);
init_pell();
new_pell(zA, zD, in, zlimit);
while (next_pell(zx, zy)) {
gmp_printf("solution (%Zd, %Zd)\n", zx, zy);
}
done_pell();
done_rootmod();
done_tau();
}