1/* Test mpq_cmp_z.
2
3Copyright 1996, 2001, 2015 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the 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
28int
29ref_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
50void
51sizes_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
98int
99main (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