xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tcmp2.c (revision ba125506a622fe649968631a56eba5d42ff57863)
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