1efee5258Smrg /* Test file for mpfr_cmp2.
2efee5258Smrg
3*ba125506Smrg Copyright 1999-2003, 2006-2023 Free Software Foundation, Inc.
4efdec83bSmrg Contributed by the AriC and Caramba projects, INRIA.
5efee5258Smrg
6efee5258Smrg This file is part of the GNU MPFR Library.
7efee5258Smrg
8efee5258Smrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9efee5258Smrg it under the terms of the GNU Lesser General Public License as published by
10efee5258Smrg the Free Software Foundation; either version 3 of the License, or (at your
11efee5258Smrg option) any later version.
12efee5258Smrg
13efee5258Smrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14efee5258Smrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15efee5258Smrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16efee5258Smrg License for more details.
17efee5258Smrg
18efee5258Smrg You should have received a copy of the GNU Lesser General Public License
19efee5258Smrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
202ba2404bSmrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21efee5258Smrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22efee5258Smrg
23efee5258Smrg #include "mpfr-test.h"
24efee5258Smrg
25efee5258Smrg /* set bit n of x to b, where bit 0 is the most significant one */
26efee5258Smrg static void
set_bit(mpfr_ptr x,unsigned int n,int b)27*ba125506Smrg set_bit (mpfr_ptr x, unsigned int n, int b)
28efee5258Smrg {
29efee5258Smrg unsigned l;
30efee5258Smrg mp_size_t xn;
31efee5258Smrg
32efee5258Smrg xn = (MPFR_PREC(x) - 1) / mp_bits_per_limb;
33efee5258Smrg l = n / mp_bits_per_limb;
34efee5258Smrg n %= mp_bits_per_limb;
35efee5258Smrg n = mp_bits_per_limb - 1 - n;
36efee5258Smrg if (b)
37299c6f0cSmrg MPFR_MANT(x)[xn - l] |= MPFR_LIMB_ONE << n;
38efee5258Smrg else
39299c6f0cSmrg MPFR_MANT(x)[xn - l] &= ~(MPFR_LIMB_ONE << n);
40efee5258Smrg }
41efee5258Smrg
42efee5258Smrg /* check that for x = 1.u 1 v 0^k low(x)
43efee5258Smrg y = 1.u 0 v 1^k low(y)
44efee5258Smrg mpfr_cmp2 (x, y) returns 1 + |u| + |v| + k for low(x) >= low(y),
45efee5258Smrg and 1 + |u| + |v| + k + 1 otherwise */
46efee5258Smrg static void
worst_cases(void)47efee5258Smrg worst_cases (void)
48efee5258Smrg {
49efee5258Smrg mpfr_t x, y;
50efee5258Smrg unsigned int i, j, k, b, expected;
51efee5258Smrg mpfr_prec_t l;
52efee5258Smrg
53efee5258Smrg mpfr_init2 (x, 200);
54efee5258Smrg mpfr_init2 (y, 200);
55efee5258Smrg
56efee5258Smrg mpfr_set_ui (y, 1, MPFR_RNDN);
57efee5258Smrg for (i = 1; i < MPFR_PREC(x); i++)
58efee5258Smrg {
59efee5258Smrg mpfr_set_ui (x, 1, MPFR_RNDN);
602ba2404bSmrg mpfr_div_2ui (y, y, 1, MPFR_RNDN); /* y = 1/2^i */
61efee5258Smrg
62efee5258Smrg l = 0;
63efee5258Smrg if (mpfr_cmp2 (x, y, &l) <= 0 || l != 1)
64efee5258Smrg {
65efee5258Smrg printf ("Error in mpfr_cmp2:\nx=");
66efee5258Smrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
67efee5258Smrg printf ("\ny=");
68efee5258Smrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
69d59437c0Smrg printf ("\ngot %lu instead of 1\n", (unsigned long) l);
70efee5258Smrg exit (1);
71efee5258Smrg }
72efee5258Smrg
73efee5258Smrg mpfr_add (x, x, y, MPFR_RNDN); /* x = 1 + 1/2^i */
74efee5258Smrg l = 0;
75efee5258Smrg if (mpfr_cmp2 (x, y, &l) <= 0 || l != 0)
76efee5258Smrg {
77efee5258Smrg printf ("Error in mpfr_cmp2:\nx=");
78efee5258Smrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
79efee5258Smrg printf ("\ny=");
80efee5258Smrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
81d59437c0Smrg printf ("\ngot %lu instead of 0\n", (unsigned long) l);
82efee5258Smrg exit (1);
83efee5258Smrg }
84efee5258Smrg }
85efee5258Smrg
86efee5258Smrg for (i = 0; i < 64; i++) /* |u| = i */
87efee5258Smrg {
88efee5258Smrg mpfr_urandomb (x, RANDS);
89efee5258Smrg mpfr_set (y, x, MPFR_RNDN);
90efee5258Smrg set_bit (x, i + 1, 1);
91efee5258Smrg set_bit (y, i + 1, 0);
92efee5258Smrg for (j = 0; j < 64; j++) /* |v| = j */
93efee5258Smrg {
94*ba125506Smrg b = RAND_BOOL ();
95efee5258Smrg set_bit (x, i + j + 2, b);
96efee5258Smrg set_bit (y, i + j + 2, b);
97efee5258Smrg for (k = 0; k < 64; k++)
98efee5258Smrg {
99efee5258Smrg if (k)
100efee5258Smrg set_bit (x, i + j + k + 1, 0);
101efee5258Smrg if (k)
102efee5258Smrg set_bit (y, i + j + k + 1, 1);
103efee5258Smrg set_bit (x, i + j + k + 2, 1);
104efee5258Smrg set_bit (y, i + j + k + 2, 0);
105efee5258Smrg l = 0; mpfr_cmp2 (x, y, &l);
106efee5258Smrg expected = i + j + k + 1;
107efee5258Smrg if (l != expected)
108efee5258Smrg {
109efee5258Smrg printf ("Error in mpfr_cmp2:\nx=");
110efee5258Smrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
111efee5258Smrg printf ("\ny=");
112efee5258Smrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
113d59437c0Smrg printf ("\ngot %lu instead of %u\n",
114d59437c0Smrg (unsigned long) l, expected);
115efee5258Smrg exit (1);
116efee5258Smrg }
117efee5258Smrg set_bit (x, i + j + k + 2, 0);
118efee5258Smrg set_bit (x, i + j + k + 3, 0);
119efee5258Smrg set_bit (y, i + j + k + 3, 1);
120efee5258Smrg l = 0; mpfr_cmp2 (x, y, &l);
121efee5258Smrg expected = i + j + k + 2;
122efee5258Smrg if (l != expected)
123efee5258Smrg {
124efee5258Smrg printf ("Error in mpfr_cmp2:\nx=");
125efee5258Smrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
126efee5258Smrg printf ("\ny=");
127efee5258Smrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
128d59437c0Smrg printf ("\ngot %lu instead of %u\n",
129d59437c0Smrg (unsigned long) l, expected);
130efee5258Smrg exit (1);
131efee5258Smrg }
132efee5258Smrg }
133efee5258Smrg }
134efee5258Smrg }
135efee5258Smrg
136efee5258Smrg mpfr_clear (x);
137efee5258Smrg mpfr_clear (y);
138efee5258Smrg }
139efee5258Smrg
140efee5258Smrg static void
tcmp2(double x,double y,int i)141efee5258Smrg tcmp2 (double x, double y, int i)
142efee5258Smrg {
143efee5258Smrg mpfr_t xx, yy;
144efee5258Smrg mpfr_prec_t j;
145efee5258Smrg
146efee5258Smrg if (i == -1)
147efee5258Smrg {
148efee5258Smrg if (x == y)
149efee5258Smrg i = 53;
150efee5258Smrg else
151efee5258Smrg i = (int) (__gmpfr_floor_log2 (x) - __gmpfr_floor_log2 (x - y));
152efee5258Smrg }
153efee5258Smrg mpfr_init2(xx, 53); mpfr_init2(yy, 53);
154efee5258Smrg mpfr_set_d (xx, x, MPFR_RNDN);
155efee5258Smrg mpfr_set_d (yy, y, MPFR_RNDN);
156efee5258Smrg j = 0;
157efee5258Smrg if (mpfr_cmp2 (xx, yy, &j) == 0)
158efee5258Smrg {
159efee5258Smrg if (x != y)
160efee5258Smrg {
161efee5258Smrg printf ("Error in mpfr_cmp2 for\nx=");
162efee5258Smrg mpfr_out_str (stdout, 2, 0, xx, MPFR_RNDN);
163efee5258Smrg printf ("\ny=");
164efee5258Smrg mpfr_out_str (stdout, 2, 0, yy, MPFR_RNDN);
165efee5258Smrg printf ("\ngot sign 0 for x != y\n");
166efee5258Smrg exit (1);
167efee5258Smrg }
168efee5258Smrg }
169efee5258Smrg else if (j != (unsigned) i)
170efee5258Smrg {
171efee5258Smrg printf ("Error in mpfr_cmp2 for\nx=");
172efee5258Smrg mpfr_out_str (stdout, 2, 0, xx, MPFR_RNDN);
173efee5258Smrg printf ("\ny=");
174efee5258Smrg mpfr_out_str (stdout, 2, 0, yy, MPFR_RNDN);
175d59437c0Smrg printf ("\ngot %lu instead of %d\n", (unsigned long) j, i);
176efee5258Smrg exit (1);
177efee5258Smrg }
178efee5258Smrg mpfr_clear(xx); mpfr_clear(yy);
179efee5258Smrg }
180efee5258Smrg
181efee5258Smrg static void
special(void)182efee5258Smrg special (void)
183efee5258Smrg {
184efee5258Smrg mpfr_t x, y;
185efee5258Smrg mpfr_prec_t j;
186efee5258Smrg
187efee5258Smrg mpfr_init (x); mpfr_init (y);
188efee5258Smrg
189efee5258Smrg /* bug found by Nathalie Revol, 21 March 2001 */
190efee5258Smrg mpfr_set_prec (x, 65);
191efee5258Smrg mpfr_set_prec (y, 65);
192efee5258Smrg mpfr_set_str_binary (x, "0.10000000000000000000000000000000000001110010010110100110011110000E1");
193efee5258Smrg mpfr_set_str_binary (y, "0.11100100101101001100111011111111110001101001000011101001001010010E-35");
194efee5258Smrg j = 0;
195efee5258Smrg if (mpfr_cmp2 (x, y, &j) <= 0 || j != 1)
196efee5258Smrg {
197efee5258Smrg printf ("Error in mpfr_cmp2:\n");
198efee5258Smrg printf ("x=");
199299c6f0cSmrg mpfr_dump (x);
200efee5258Smrg printf ("y=");
201299c6f0cSmrg mpfr_dump (y);
202d59437c0Smrg printf ("got %lu, expected 1\n", (unsigned long) j);
203efee5258Smrg exit (1);
204efee5258Smrg }
205efee5258Smrg
206efee5258Smrg mpfr_set_prec(x, 127); mpfr_set_prec(y, 127);
207efee5258Smrg mpfr_set_str_binary(x, "0.1011010000110111111000000101011110110001000101101011011110010010011110010000101101000010011001100110010000000010110000101000101E6");
208efee5258Smrg mpfr_set_str_binary(y, "0.1011010000110111111000000101011011111100011101000011001111000010100010100110110100110010011001100110010000110010010110000010110E6");
209efee5258Smrg j = 0;
210efee5258Smrg if (mpfr_cmp2(x, y, &j) <= 0 || j != 32)
211efee5258Smrg {
212efee5258Smrg printf ("Error in mpfr_cmp2:\n");
213299c6f0cSmrg printf ("x="); mpfr_dump (x);
214299c6f0cSmrg printf ("y="); mpfr_dump (y);
215d59437c0Smrg printf ("got %lu, expected 32\n", (unsigned long) j);
216efee5258Smrg exit (1);
217efee5258Smrg }
218efee5258Smrg
219efee5258Smrg mpfr_set_prec (x, 128); mpfr_set_prec (y, 239);
220efee5258Smrg mpfr_set_str_binary (x, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100100000000000E167");
221efee5258Smrg mpfr_set_str_binary (y, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100011111111111111111111111111111111111111111111111011111100101011100011001101000100111000010000000000101100110000111111000101E167");
222efee5258Smrg j = 0;
223efee5258Smrg if (mpfr_cmp2(x, y, &j) <= 0 || j != 164)
224efee5258Smrg {
225efee5258Smrg printf ("Error in mpfr_cmp2:\n");
226299c6f0cSmrg printf ("x="); mpfr_dump (x);
227299c6f0cSmrg printf ("y="); mpfr_dump (y);
228d59437c0Smrg printf ("got %lu, expected 164\n", (unsigned long) j);
229efee5258Smrg exit (1);
230efee5258Smrg }
231efee5258Smrg
232efee5258Smrg /* bug found by Nathalie Revol, 29 March 2001 */
233efee5258Smrg mpfr_set_prec (x, 130); mpfr_set_prec (y, 130);
234efee5258Smrg mpfr_set_str_binary (x, "0.1100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E2");
235efee5258Smrg mpfr_set_str_binary (y, "0.1011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100E2");
236efee5258Smrg j = 0;
237efee5258Smrg if (mpfr_cmp2(x, y, &j) <= 0 || j != 127)
238efee5258Smrg {
239efee5258Smrg printf ("Error in mpfr_cmp2:\n");
240299c6f0cSmrg printf ("x="); mpfr_dump (x);
241299c6f0cSmrg printf ("y="); mpfr_dump (y);
242d59437c0Smrg printf ("got %lu, expected 127\n", (unsigned long) j);
243efee5258Smrg exit (1);
244efee5258Smrg }
245efee5258Smrg
246efee5258Smrg /* bug found by Nathalie Revol, 2 Apr 2001 */
247efee5258Smrg mpfr_set_prec (x, 65); mpfr_set_prec (y, 65);
248efee5258Smrg mpfr_set_ui (x, 5, MPFR_RNDN);
249efee5258Smrg mpfr_set_str_binary (y, "0.10011111111111111111111111111111111111111111111111111111111111101E3");
250efee5258Smrg j = 0;
251efee5258Smrg if (mpfr_cmp2(x, y, &j) <= 0 || j != 63)
252efee5258Smrg {
253efee5258Smrg printf ("Error in mpfr_cmp2:\n");
254299c6f0cSmrg printf ("x="); mpfr_dump (x);
255299c6f0cSmrg printf ("y="); mpfr_dump (y);
256d59437c0Smrg printf ("got %lu, expected 63\n", (unsigned long) j);
257efee5258Smrg exit (1);
258efee5258Smrg }
259efee5258Smrg
260efee5258Smrg /* bug found by Nathalie Revol, 2 Apr 2001 */
261efee5258Smrg mpfr_set_prec (x, 65); mpfr_set_prec (y, 65);
262efee5258Smrg mpfr_set_str_binary (x, "0.10011011111000101001110000000000000000000000000000000000000000000E-69");
263efee5258Smrg mpfr_set_str_binary (y, "0.10011011111000101001101111111111111111111111111111111111111111101E-69");
264efee5258Smrg j = 0;
265efee5258Smrg if (mpfr_cmp2(x, y, &j) <= 0 || j != 63)
266efee5258Smrg {
267efee5258Smrg printf ("Error in mpfr_cmp2:\n");
268299c6f0cSmrg printf ("x="); mpfr_dump (x);
269299c6f0cSmrg printf ("y="); mpfr_dump (y);
270d59437c0Smrg printf ("got %lu, expected 63\n", (unsigned long) j);
271efee5258Smrg exit (1);
272efee5258Smrg }
273efee5258Smrg
274efee5258Smrg mpfr_set_prec (x, 65);
275efee5258Smrg mpfr_set_prec (y, 32);
276efee5258Smrg mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
277efee5258Smrg mpfr_set_str_binary (y, "0.11101110111100011101110111111111");
278efee5258Smrg if (mpfr_cmp2 (x, y, &j) <= 0 || j != 0)
279efee5258Smrg {
280efee5258Smrg printf ("Error in mpfr_cmp2 (1)\n");
281efee5258Smrg exit (1);
282efee5258Smrg }
283efee5258Smrg
284efee5258Smrg mpfr_set_prec (x, 2 * GMP_NUMB_BITS);
285efee5258Smrg mpfr_set_prec (y, GMP_NUMB_BITS);
286efee5258Smrg mpfr_set_ui (x, 1, MPFR_RNDN); /* x = 1 */
287efee5258Smrg mpfr_set_ui (y, 1, MPFR_RNDN);
288efee5258Smrg mpfr_nextbelow (y); /* y = 1 - 2^(-GMP_NUMB_BITS) */
289efee5258Smrg mpfr_cmp2 (x, y, &j);
290efee5258Smrg if (mpfr_cmp2 (x, y, &j) <= 0 || j != GMP_NUMB_BITS)
291efee5258Smrg {
292efee5258Smrg printf ("Error in mpfr_cmp2 (2)\n");
293efee5258Smrg exit (1);
294efee5258Smrg }
295efee5258Smrg
296efee5258Smrg mpfr_clear (x);
297efee5258Smrg mpfr_clear (y);
298efee5258Smrg }
299efee5258Smrg
300299c6f0cSmrg /* Compare (m,kx) and (m,ky), where (m,k) means m fixed limbs followed by
301299c6f0cSmrg k zero limbs. */
302299c6f0cSmrg static void
test_equal(void)303299c6f0cSmrg test_equal (void)
304299c6f0cSmrg {
305299c6f0cSmrg mpfr_t w, x, y;
306299c6f0cSmrg int m, kx, ky, inex;
307299c6f0cSmrg mpfr_prec_t j;
308299c6f0cSmrg
309299c6f0cSmrg for (m = 1; m <= 4; m++)
310299c6f0cSmrg {
311299c6f0cSmrg mpfr_init2 (w, m * GMP_NUMB_BITS);
312299c6f0cSmrg for (kx = 0; kx <= 4; kx++)
313299c6f0cSmrg for (ky = 0; ky <= 4; ky++)
314299c6f0cSmrg {
315299c6f0cSmrg do mpfr_urandomb (w, RANDS); while (mpfr_zero_p (w));
316299c6f0cSmrg mpfr_init2 (x, (m + kx) * GMP_NUMB_BITS
317299c6f0cSmrg - (kx == 0 ? 0 : randlimb () % GMP_NUMB_BITS));
318299c6f0cSmrg mpfr_init2 (y, (m + ky) * GMP_NUMB_BITS
319299c6f0cSmrg - (ky == 0 ? 0 : randlimb () % GMP_NUMB_BITS));
320299c6f0cSmrg inex = mpfr_set (x, w, MPFR_RNDN);
321299c6f0cSmrg MPFR_ASSERTN (inex == 0);
322299c6f0cSmrg inex = mpfr_set (y, w, MPFR_RNDN);
323299c6f0cSmrg MPFR_ASSERTN (inex == 0);
324299c6f0cSmrg MPFR_ASSERTN (mpfr_equal_p (x, y));
325*ba125506Smrg if (RAND_BOOL ())
326299c6f0cSmrg mpfr_neg (x, x, MPFR_RNDN);
327*ba125506Smrg if (RAND_BOOL ())
328299c6f0cSmrg mpfr_neg (y, y, MPFR_RNDN);
329299c6f0cSmrg if (mpfr_cmp2 (x, y, &j) != 0)
330299c6f0cSmrg {
331299c6f0cSmrg printf ("Error in test_equal for m = %d, kx = %d, ky = %d\n",
332299c6f0cSmrg m, kx, ky);
333299c6f0cSmrg printf (" x = ");
334299c6f0cSmrg mpfr_dump (x);
335299c6f0cSmrg printf (" y = ");
336299c6f0cSmrg mpfr_dump (y);
337299c6f0cSmrg exit (1);
338299c6f0cSmrg }
339299c6f0cSmrg mpfr_clears (x, y, (mpfr_ptr) 0);
340299c6f0cSmrg }
341299c6f0cSmrg mpfr_clear (w);
342299c6f0cSmrg }
343299c6f0cSmrg }
344299c6f0cSmrg
345efee5258Smrg int
main(void)346efee5258Smrg main (void)
347efee5258Smrg {
348efee5258Smrg int i;
349efee5258Smrg long j;
350efee5258Smrg double x, y, z;
351efee5258Smrg
352efee5258Smrg tests_start_mpfr ();
353efee5258Smrg mpfr_test_init ();
354efee5258Smrg
355efee5258Smrg worst_cases ();
356efee5258Smrg special ();
357efee5258Smrg tcmp2 (5.43885304644369510000e+185, -1.87427265794105340000e-57, 1);
358efee5258Smrg tcmp2 (1.06022698059744327881e+71, 1.05824655795525779205e+71, -1);
359efee5258Smrg tcmp2 (1.0, 1.0, 53);
360efee5258Smrg /* warning: cmp2 does not allow 0 as input */
361efee5258Smrg for (x = 0.5, i = 1; i < 54; i++)
362efee5258Smrg {
363efee5258Smrg tcmp2 (1.0, 1.0-x, i);
364efee5258Smrg x /= 2.0;
365efee5258Smrg }
366efee5258Smrg for (x = 0.5, i = 1; i < 100; i++)
367efee5258Smrg {
368efee5258Smrg tcmp2 (1.0, x, 1);
369efee5258Smrg x /= 2.0;
370efee5258Smrg }
371efee5258Smrg for (j = 0; j < 100000; j++)
372efee5258Smrg {
373efee5258Smrg x = DBL_RAND ();
374efee5258Smrg y = DBL_RAND ();
375efee5258Smrg if (x < y)
376efee5258Smrg {
377efee5258Smrg z = x;
378efee5258Smrg x = y;
379efee5258Smrg y = z;
380efee5258Smrg }
381efee5258Smrg if (y != 0.0)
382efee5258Smrg tcmp2 (x, y, -1);
383efee5258Smrg }
384efee5258Smrg
385299c6f0cSmrg test_equal ();
386299c6f0cSmrg
387efee5258Smrg tests_end_mpfr ();
388efee5258Smrg
389efee5258Smrg return 0;
390efee5258Smrg }
391