xref: /netbsd/external/lgpl3/gmp/dist/tests/mpf/t-eq.c (revision 671ea119)
14a1767b4Smrg /* Test mpf_eq.
24a1767b4Smrg 
3d25e02daSmrg Copyright 2009, 2012 Free Software Foundation, Inc.
44a1767b4Smrg 
5d25e02daSmrg This file is part of the GNU MP Library test suite.
64a1767b4Smrg 
7d25e02daSmrg The GNU MP Library test suite is free software; you can redistribute it
8d25e02daSmrg and/or modify it under the terms of the GNU General Public License as
9d25e02daSmrg published by the Free Software Foundation; either version 3 of the License,
10d25e02daSmrg or (at your option) any later version.
114a1767b4Smrg 
12d25e02daSmrg The GNU MP Library test suite is distributed in the hope that it will be
13d25e02daSmrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14d25e02daSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15d25e02daSmrg Public License for more details.
164a1767b4Smrg 
17d25e02daSmrg You should have received a copy of the GNU General Public License along with
18*f81b1c5bSmrg the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
194a1767b4Smrg 
204a1767b4Smrg #include <stdio.h>
214a1767b4Smrg #include <stdlib.h>
224a1767b4Smrg 
234a1767b4Smrg #include "gmp-impl.h"
244a1767b4Smrg #include "tests.h"
254a1767b4Smrg 
264a1767b4Smrg #define SZ (2 * sizeof(mp_limb_t))
274a1767b4Smrg 
284a1767b4Smrg void insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr);
294a1767b4Smrg void dump_abort (mpf_t, mpf_t, int, int, int, int, int, long);
304a1767b4Smrg void hexdump (mpf_t);
314a1767b4Smrg 
32d25e02daSmrg void
check_data(void)33d25e02daSmrg check_data (void)
344a1767b4Smrg {
35d25e02daSmrg   static const struct
36d25e02daSmrg   {
37d25e02daSmrg     struct {
38d25e02daSmrg       int        exp, size;
39d25e02daSmrg       mp_limb_t  d[10];
40d25e02daSmrg     } x, y;
41d25e02daSmrg     mp_bitcnt_t bits;
42d25e02daSmrg     int want;
43d25e02daSmrg 
44d25e02daSmrg   } data[] = {
45d25e02daSmrg     { { 0, 0, { 0 } },             { 0, 0, { 0 } },    0, 1 },
46d25e02daSmrg 
47d25e02daSmrg     { { 0, 1, { 7 } },             { 0, 1, { 7 } },    0, 1 },
48d25e02daSmrg     { { 0, 1, { 7 } },             { 0, 1, { 7 } },   17, 1 },
49d25e02daSmrg     { { 0, 1, { 7 } },             { 0, 1, { 7 } }, 4711, 1 },
50d25e02daSmrg 
51d25e02daSmrg     { { 0, 1, { 7 } },             { 0, 1, { 6 } },    0, 1 },
52d25e02daSmrg     { { 0, 1, { 7 } },             { 0, 1, { 6 } },    2, 1 },
53d25e02daSmrg     { { 0, 1, { 7 } },             { 0, 1, { 6 } },    3, 0 },
54d25e02daSmrg 
55d25e02daSmrg     { { 0, 0, { 0 } },             { 0, 1, { 1 } },    0, 0 },
56d25e02daSmrg     { { 0, 1, { 1 } },             { 0,-1 ,{ 1 } },    0, 0 },
57d25e02daSmrg     { { 1, 1, { 1 } },             { 0, 1, { 1 } },    0, 0 },
58d25e02daSmrg 
59d25e02daSmrg     { { 0, 1, { 8 } },             { 0, 1, { 4 } },    0, 0 },
60d25e02daSmrg 
61d25e02daSmrg     { { 0, 2, { 0, 3 } },          { 0, 1, { 3 } }, 1000, 1 },
62d25e02daSmrg   };
63d25e02daSmrg 
64d25e02daSmrg   mpf_t  x, y;
65d25e02daSmrg   int got, got_swapped;
66d25e02daSmrg   int i;
67d25e02daSmrg   mp_trace_base = 16;
68d25e02daSmrg 
69d25e02daSmrg   for (i = 0; i < numberof (data); i++)
70d25e02daSmrg     {
71d25e02daSmrg       PTR(x) = (mp_ptr) data[i].x.d;
72d25e02daSmrg       SIZ(x) = data[i].x.size;
73d25e02daSmrg       EXP(x) = data[i].x.exp;
74d25e02daSmrg       PREC(x) = numberof (data[i].x.d);
75d25e02daSmrg       MPF_CHECK_FORMAT (x);
76d25e02daSmrg 
77d25e02daSmrg       PTR(y) = (mp_ptr) data[i].y.d;
78d25e02daSmrg       SIZ(y) = data[i].y.size;
79d25e02daSmrg       EXP(y) = data[i].y.exp;
80d25e02daSmrg       PREC(y) = numberof (data[i].y.d);
81d25e02daSmrg       MPF_CHECK_FORMAT (y);
82d25e02daSmrg 
83d25e02daSmrg       got         = mpf_eq (x, y, data[i].bits);
84d25e02daSmrg       got_swapped = mpf_eq (y, x, data[i].bits);
85d25e02daSmrg 
86d25e02daSmrg       if (got != got_swapped || got != data[i].want)
87d25e02daSmrg 	{
88*f81b1c5bSmrg 	  printf ("check_data() wrong result at data[%d]\n", i);
89d25e02daSmrg 	  mpf_trace ("x   ", x);
90d25e02daSmrg 	  mpf_trace ("y   ", y);
91d25e02daSmrg 	  printf ("got         %d\n", got);
92d25e02daSmrg 	  printf ("got_swapped %d\n", got_swapped);
93d25e02daSmrg 	  printf ("want        %d\n", data[i].want);
94d25e02daSmrg 	  abort ();
95d25e02daSmrg         }
96d25e02daSmrg     }
97d25e02daSmrg }
98d25e02daSmrg 
99d25e02daSmrg void
check_random(long reps)100d25e02daSmrg check_random (long reps)
101d25e02daSmrg {
102d25e02daSmrg   unsigned long test;
103d25e02daSmrg   gmp_randstate_ptr rands = RANDS;
1044a1767b4Smrg   mpf_t a, b, x;
1054a1767b4Smrg   mpz_t ds;
1064a1767b4Smrg   int hibits, lshift1, lshift2;
1074a1767b4Smrg   int xtra;
1084a1767b4Smrg 
1094a1767b4Smrg #define HIBITS 10
1104a1767b4Smrg #define LSHIFT1 10
1114a1767b4Smrg #define LSHIFT2 10
1124a1767b4Smrg 
1134a1767b4Smrg   mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2));
1144a1767b4Smrg 
1154a1767b4Smrg   mpz_init (ds);
1164a1767b4Smrg   mpf_inits (a, b, x, NULL);
1174a1767b4Smrg 
1184a1767b4Smrg   for (test = 0; test < reps; test++)
1194a1767b4Smrg     {
1204a1767b4Smrg       mpz_urandomb (ds, rands, HIBITS);
1214a1767b4Smrg       hibits = mpz_get_ui (ds) + 1;
1224a1767b4Smrg       mpz_urandomb (ds, rands, hibits);
1234a1767b4Smrg       mpz_setbit (ds, hibits  - 1);	/* make sure msb is set */
1244a1767b4Smrg       mpf_set_z (a, ds);
1254a1767b4Smrg       mpf_set_z (b, ds);
1264a1767b4Smrg 
1274a1767b4Smrg       mpz_urandomb (ds, rands, LSHIFT1);
1284a1767b4Smrg       lshift1 = mpz_get_ui (ds);
1294a1767b4Smrg       mpf_mul_2exp (a, a, lshift1 + 1);
1304a1767b4Smrg       mpf_mul_2exp (b, b, lshift1 + 1);
1314a1767b4Smrg       mpf_add_ui (a, a, 1);	/* make a one-bit difference */
1324a1767b4Smrg 
1334a1767b4Smrg       mpz_urandomb (ds, rands, LSHIFT2);
1344a1767b4Smrg       lshift2 = mpz_get_ui (ds);
1354a1767b4Smrg       mpf_mul_2exp (a, a, lshift2);
1364a1767b4Smrg       mpf_mul_2exp (b, b, lshift2);
1374a1767b4Smrg       mpz_urandomb (ds, rands, lshift2);
1384a1767b4Smrg       mpf_set_z (x, ds);
1394a1767b4Smrg       mpf_add (a, a, x);
1404a1767b4Smrg       mpf_add (b, b, x);
1414a1767b4Smrg 
1424a1767b4Smrg       insert_random_low_zero_limbs (a, rands);
1434a1767b4Smrg       insert_random_low_zero_limbs (b, rands);
1444a1767b4Smrg 
145d25e02daSmrg       if (mpf_eq (a, b, lshift1 + hibits) == 0 ||
146d25e02daSmrg 	  mpf_eq (b, a, lshift1 + hibits) == 0)
1474a1767b4Smrg 	{
1484a1767b4Smrg 	  dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test);
1494a1767b4Smrg 	}
1504a1767b4Smrg       for (xtra = 1; xtra < 100; xtra++)
151d25e02daSmrg 	if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0 ||
152d25e02daSmrg 	    mpf_eq (b, a, lshift1 + hibits + xtra) != 0)
1534a1767b4Smrg 	  {
1544a1767b4Smrg 	    dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test);
1554a1767b4Smrg 	  }
1564a1767b4Smrg     }
1574a1767b4Smrg 
1584a1767b4Smrg   mpf_clears (a, b, x, NULL);
1594a1767b4Smrg   mpz_clear (ds);
1604a1767b4Smrg }
1614a1767b4Smrg 
1624a1767b4Smrg void
insert_random_low_zero_limbs(mpf_t x,gmp_randstate_ptr rands)1634a1767b4Smrg insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands)
1644a1767b4Smrg {
1654a1767b4Smrg   mp_size_t max = PREC(x) - SIZ(x);
1664a1767b4Smrg   mp_size_t s;
1674a1767b4Smrg   mpz_t ds; mpz_init (ds);
1684a1767b4Smrg   mpz_urandomb (ds, rands, 32);
1694a1767b4Smrg   s = mpz_get_ui (ds) % (max + 1);
1704a1767b4Smrg   MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x));
1714a1767b4Smrg   MPN_ZERO (PTR(x), s);
1724a1767b4Smrg   SIZ(x) += s;
1734a1767b4Smrg   mpz_clear (ds);
1744a1767b4Smrg }
1754a1767b4Smrg 
1764a1767b4Smrg void
dump_abort(mpf_t a,mpf_t b,int cmp_prec,int lshift1,int lshift2,int hibits,int want,long test)1774a1767b4Smrg dump_abort (mpf_t a, mpf_t b, int cmp_prec, int lshift1, int lshift2, int hibits, int want, long test)
1784a1767b4Smrg {
1794a1767b4Smrg   printf ("ERROR in test %ld\n", test);
1804a1767b4Smrg   printf ("want %d got %d from mpf_eq\n", want, 1-want);
1814a1767b4Smrg   printf ("cmp_prec = %d\n", cmp_prec);
1824a1767b4Smrg   printf ("lshift1 = %d\n", lshift1);
1834a1767b4Smrg   printf ("lshift2 = %d\n", lshift2);
1844a1767b4Smrg   printf ("hibits = %d\n", hibits);
1854a1767b4Smrg   hexdump (a); puts ("");
1864a1767b4Smrg   hexdump (b); puts ("");
1874a1767b4Smrg   abort ();
1884a1767b4Smrg }
1894a1767b4Smrg 
1904a1767b4Smrg void
hexdump(mpf_t x)1914a1767b4Smrg hexdump (mpf_t x)
1924a1767b4Smrg {
1934a1767b4Smrg   mp_size_t i;
1944a1767b4Smrg   for (i = ABSIZ(x) - 1; i >= 0; i--)
1954a1767b4Smrg     {
1964a1767b4Smrg       gmp_printf ("%0*MX", SZ, PTR(x)[i]);
1974a1767b4Smrg       if (i != 0)
1984a1767b4Smrg 	printf (" ");
1994a1767b4Smrg     }
2004a1767b4Smrg }
201d25e02daSmrg 
202d25e02daSmrg int
main(int argc,char * argv[])203d25e02daSmrg main (int argc, char *argv[])
204d25e02daSmrg {
205d25e02daSmrg   long reps = 10000;
206d25e02daSmrg 
207d25e02daSmrg   if (argc == 2)
208d25e02daSmrg     reps = strtol (argv[1], 0, 0);
209d25e02daSmrg 
210d25e02daSmrg   tests_start ();
211d25e02daSmrg 
212d25e02daSmrg   check_data ();
213d25e02daSmrg   check_random (reps);
214d25e02daSmrg 
215d25e02daSmrg   tests_end ();
216d25e02daSmrg   exit (0);
217d25e02daSmrg }
218