xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpq/t-cmp_z.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
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