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