xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpf/t-eq.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
1 /* Test mpf_eq.
2 
3 Copyright 2009, 2012 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 SZ (2 * sizeof(mp_limb_t))
27 
28 void insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr);
29 void dump_abort (mpf_t, mpf_t, int, int, int, int, int, long);
30 void hexdump (mpf_t);
31 
32 void
check_data(void)33 check_data (void)
34 {
35   static const struct
36   {
37     struct {
38       int        exp, size;
39       mp_limb_t  d[10];
40     } x, y;
41     mp_bitcnt_t bits;
42     int want;
43 
44   } data[] = {
45     { { 0, 0, { 0 } },             { 0, 0, { 0 } },    0, 1 },
46 
47     { { 0, 1, { 7 } },             { 0, 1, { 7 } },    0, 1 },
48     { { 0, 1, { 7 } },             { 0, 1, { 7 } },   17, 1 },
49     { { 0, 1, { 7 } },             { 0, 1, { 7 } }, 4711, 1 },
50 
51     { { 0, 1, { 7 } },             { 0, 1, { 6 } },    0, 1 },
52     { { 0, 1, { 7 } },             { 0, 1, { 6 } },    2, 1 },
53     { { 0, 1, { 7 } },             { 0, 1, { 6 } },    3, 0 },
54 
55     { { 0, 0, { 0 } },             { 0, 1, { 1 } },    0, 0 },
56     { { 0, 1, { 1 } },             { 0,-1 ,{ 1 } },    0, 0 },
57     { { 1, 1, { 1 } },             { 0, 1, { 1 } },    0, 0 },
58 
59     { { 0, 1, { 8 } },             { 0, 1, { 4 } },    0, 0 },
60 
61     { { 0, 2, { 0, 3 } },          { 0, 1, { 3 } }, 1000, 1 },
62   };
63 
64   mpf_t  x, y;
65   int got, got_swapped;
66   int i;
67   mp_trace_base = 16;
68 
69   for (i = 0; i < numberof (data); i++)
70     {
71       PTR(x) = (mp_ptr) data[i].x.d;
72       SIZ(x) = data[i].x.size;
73       EXP(x) = data[i].x.exp;
74       PREC(x) = numberof (data[i].x.d);
75       MPF_CHECK_FORMAT (x);
76 
77       PTR(y) = (mp_ptr) data[i].y.d;
78       SIZ(y) = data[i].y.size;
79       EXP(y) = data[i].y.exp;
80       PREC(y) = numberof (data[i].y.d);
81       MPF_CHECK_FORMAT (y);
82 
83       got         = mpf_eq (x, y, data[i].bits);
84       got_swapped = mpf_eq (y, x, data[i].bits);
85 
86       if (got != got_swapped || got != data[i].want)
87 	{
88 	  printf ("check_data() wrong result at data[%d]\n", i);
89 	  mpf_trace ("x   ", x);
90 	  mpf_trace ("y   ", y);
91 	  printf ("got         %d\n", got);
92 	  printf ("got_swapped %d\n", got_swapped);
93 	  printf ("want        %d\n", data[i].want);
94 	  abort ();
95         }
96     }
97 }
98 
99 void
check_random(long reps)100 check_random (long reps)
101 {
102   unsigned long test;
103   gmp_randstate_ptr rands = RANDS;
104   mpf_t a, b, x;
105   mpz_t ds;
106   int hibits, lshift1, lshift2;
107   int xtra;
108 
109 #define HIBITS 10
110 #define LSHIFT1 10
111 #define LSHIFT2 10
112 
113   mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2));
114 
115   mpz_init (ds);
116   mpf_inits (a, b, x, NULL);
117 
118   for (test = 0; test < reps; test++)
119     {
120       mpz_urandomb (ds, rands, HIBITS);
121       hibits = mpz_get_ui (ds) + 1;
122       mpz_urandomb (ds, rands, hibits);
123       mpz_setbit (ds, hibits  - 1);	/* make sure msb is set */
124       mpf_set_z (a, ds);
125       mpf_set_z (b, ds);
126 
127       mpz_urandomb (ds, rands, LSHIFT1);
128       lshift1 = mpz_get_ui (ds);
129       mpf_mul_2exp (a, a, lshift1 + 1);
130       mpf_mul_2exp (b, b, lshift1 + 1);
131       mpf_add_ui (a, a, 1);	/* make a one-bit difference */
132 
133       mpz_urandomb (ds, rands, LSHIFT2);
134       lshift2 = mpz_get_ui (ds);
135       mpf_mul_2exp (a, a, lshift2);
136       mpf_mul_2exp (b, b, lshift2);
137       mpz_urandomb (ds, rands, lshift2);
138       mpf_set_z (x, ds);
139       mpf_add (a, a, x);
140       mpf_add (b, b, x);
141 
142       insert_random_low_zero_limbs (a, rands);
143       insert_random_low_zero_limbs (b, rands);
144 
145       if (mpf_eq (a, b, lshift1 + hibits) == 0 ||
146 	  mpf_eq (b, a, lshift1 + hibits) == 0)
147 	{
148 	  dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test);
149 	}
150       for (xtra = 1; xtra < 100; xtra++)
151 	if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0 ||
152 	    mpf_eq (b, a, lshift1 + hibits + xtra) != 0)
153 	  {
154 	    dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test);
155 	  }
156     }
157 
158   mpf_clears (a, b, x, NULL);
159   mpz_clear (ds);
160 }
161 
162 void
insert_random_low_zero_limbs(mpf_t x,gmp_randstate_ptr rands)163 insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands)
164 {
165   mp_size_t max = PREC(x) - SIZ(x);
166   mp_size_t s;
167   mpz_t ds; mpz_init (ds);
168   mpz_urandomb (ds, rands, 32);
169   s = mpz_get_ui (ds) % (max + 1);
170   MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x));
171   MPN_ZERO (PTR(x), s);
172   SIZ(x) += s;
173   mpz_clear (ds);
174 }
175 
176 void
dump_abort(mpf_t a,mpf_t b,int cmp_prec,int lshift1,int lshift2,int hibits,int want,long test)177 dump_abort (mpf_t a, mpf_t b, int cmp_prec, int lshift1, int lshift2, int hibits, int want, long test)
178 {
179   printf ("ERROR in test %ld\n", test);
180   printf ("want %d got %d from mpf_eq\n", want, 1-want);
181   printf ("cmp_prec = %d\n", cmp_prec);
182   printf ("lshift1 = %d\n", lshift1);
183   printf ("lshift2 = %d\n", lshift2);
184   printf ("hibits = %d\n", hibits);
185   hexdump (a); puts ("");
186   hexdump (b); puts ("");
187   abort ();
188 }
189 
190 void
hexdump(mpf_t x)191 hexdump (mpf_t x)
192 {
193   mp_size_t i;
194   for (i = ABSIZ(x) - 1; i >= 0; i--)
195     {
196       gmp_printf ("%0*MX", SZ, PTR(x)[i]);
197       if (i != 0)
198 	printf (" ");
199     }
200 }
201 
202 int
main(int argc,char * argv[])203 main (int argc, char *argv[])
204 {
205   long reps = 10000;
206 
207   if (argc == 2)
208     reps = strtol (argv[1], 0, 0);
209 
210   tests_start ();
211 
212   check_data ();
213   check_random (reps);
214 
215   tests_end ();
216   exit (0);
217 }
218