blob: 7b80b027a7b9eb50edf787d07c85727c61b0fe94 [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001/* Test mpf_eq.
2
3Copyright 2009, 2012 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 SZ (2 * sizeof(mp_limb_t))
27
28void insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr);
29void dump_abort (mpf_t, mpf_t, int, int, int, int, int, long);
30void hexdump (mpf_t);
31
32void
33check_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
99void
100check_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
162void
163insert_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
176void
177dump_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
190void
191hexdump (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
202int
203main (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}