1 /* Test mpq_cmp_z.
2
3 Copyright 1996, 2001, 2015 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library test suite.
6
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 Public License for more details.
16
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include "gmp-impl.h"
24 #include "tests.h"
25
26 #define SGN(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0)
27
28 int
ref_mpq_cmp_z(mpq_t a,mpz_t b)29 ref_mpq_cmp_z (mpq_t a, mpz_t b)
30 {
31 mpz_t bi;
32 int cc;
33
34 mpz_init (bi);
35
36 mpz_mul (bi, b, DEN (a));
37 cc = mpz_cmp (NUM (a), bi);
38 mpz_clear (bi);
39 return cc;
40 }
41
42 #ifndef SIZE
43 #define SIZE 8 /* increasing this lowers the probability of finding an error */
44 #endif
45
46 #ifndef MAXN
47 #define MAXN 5 /* increasing this impatcs on total timing */
48 #endif
49
50 void
sizes_test(int m)51 sizes_test (int m)
52 {
53 mpq_t a;
54 mpz_t b;
55 int i, j, k, s;
56 int cc, ccref;
57
58 mpq_init (a);
59 mpz_init (b);
60
61 for (i = 0; i <= MAXN ; ++i)
62 {
63 mpz_setbit (DEN (a), i*m); /* \sum_0^i 2^(i*m) */
64 for (j = 0; j <= MAXN; ++j)
65 {
66 mpz_set_ui (NUM (a), 0);
67 mpz_setbit (NUM (a), j*m); /* 2^(j*m) */
68 for (k = 0; k <= MAXN; ++k)
69 {
70 mpz_set_ui (b, 0);
71 mpz_setbit (b, k*m); /* 2^(k*m) */
72 if (i == 0) /* Denominator is 1, compare the two exponents */
73 ccref = (j>k)-(j<k);
74 else
75 ccref = j-i > k ? 1 : -1;
76 for (s = 1; s >= -1; s -= 2)
77 {
78 cc = mpq_cmp_z (a, b);
79
80 if (ccref != SGN (cc))
81 {
82 fprintf (stderr, "i=%i, j=%i, k=%i, m=%i, s=%i\n; ccref= %i, cc= %i\n", i, j, k, m, s, ccref, cc);
83 abort ();
84 }
85
86 mpq_neg (a, a);
87 mpz_neg (b, b);
88 ccref = - ccref;
89 }
90 }
91 }
92 }
93
94 mpq_clear (a);
95 mpz_clear (b);
96 }
97
98 int
main(int argc,char ** argv)99 main (int argc, char **argv)
100 {
101 mpq_t a;
102 mpz_t b;
103 mp_size_t size;
104 int reps = 10000;
105 int i;
106 int cc, ccref;
107
108 tests_start ();
109
110 if (argc == 2)
111 reps = atoi (argv[1]);
112
113 mpq_init (a);
114 mpz_init (b);
115
116 for (i = 0; i < reps; i++)
117 {
118 if (i % 8192 == 0)
119 sizes_test (urandom () % (i + 1) + 1);
120 size = urandom () % SIZE - SIZE/2;
121 mpz_random2 (NUM (a), size);
122 do
123 {
124 size = urandom () % (SIZE/2);
125 mpz_random2 (DEN (a), size);
126 }
127 while (mpz_cmp_ui (DEN (a), 0) == 0);
128
129 size = urandom () % SIZE - SIZE/2;
130 mpz_random2 (b, size);
131
132 mpq_canonicalize (a);
133
134 ccref = ref_mpq_cmp_z (a, b);
135 cc = mpq_cmp_z (a, b);
136
137 if (SGN (ccref) != SGN (cc))
138 abort ();
139 }
140
141 mpq_clear (a);
142 mpz_clear (b);
143
144 tests_end ();
145 exit (0);
146 }
147