t-eq.c revision 1.1.1.1
1/* Test mpf_eq.
2
3Copyright 2009 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19
20#include <stdio.h>
21#include <stdlib.h>
22
23#include "gmp.h"
24#include "gmp-impl.h"
25#include "tests.h"
26
27#define SZ (2 * sizeof(mp_limb_t))
28
29void insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr);
30void dump_abort (mpf_t, mpf_t, int, int, int, int, int, long);
31void hexdump (mpf_t);
32
33int
34main (int argc, char **argv)
35{
36  unsigned long test, reps = 10000;
37  mpf_t a, b, x;
38  gmp_randstate_ptr rands;
39  mpz_t ds;
40  int hibits, lshift1, lshift2;
41  int xtra;
42
43#define HIBITS 10
44#define LSHIFT1 10
45#define LSHIFT2 10
46
47  if (argc > 1)
48    reps = strtol (argv[1], 0, 0);
49
50  tests_start ();
51
52  rands = RANDS;
53
54  mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2));
55
56  mpz_init (ds);
57  mpf_inits (a, b, x, NULL);
58
59  for (test = 0; test < reps; test++)
60    {
61      mpz_urandomb (ds, rands, HIBITS);
62      hibits = mpz_get_ui (ds) + 1;
63      mpz_urandomb (ds, rands, hibits);
64      mpz_setbit (ds, hibits  - 1);	/* make sure msb is set */
65      mpf_set_z (a, ds);
66      mpf_set_z (b, ds);
67
68      mpz_urandomb (ds, rands, LSHIFT1);
69      lshift1 = mpz_get_ui (ds);
70      mpf_mul_2exp (a, a, lshift1 + 1);
71      mpf_mul_2exp (b, b, lshift1 + 1);
72      mpf_add_ui (a, a, 1);	/* make a one-bit difference */
73
74      mpz_urandomb (ds, rands, LSHIFT2);
75      lshift2 = mpz_get_ui (ds);
76      mpf_mul_2exp (a, a, lshift2);
77      mpf_mul_2exp (b, b, lshift2);
78      mpz_urandomb (ds, rands, lshift2);
79      mpf_set_z (x, ds);
80      mpf_add (a, a, x);
81      mpf_add (b, b, x);
82
83      insert_random_low_zero_limbs (a, rands);
84      insert_random_low_zero_limbs (b, rands);
85
86      if (mpf_eq (a, b, lshift1 + hibits) == 0)
87	{
88	  dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test);
89	}
90      for (xtra = 1; xtra < 100; xtra++)
91	if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0)
92	  {
93	    dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test);
94	  }
95    }
96
97  mpf_clears (a, b, x, NULL);
98  mpz_clear (ds);
99  tests_end ();
100  exit (0);
101}
102
103void
104insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands)
105{
106  mp_size_t max = PREC(x) - SIZ(x);
107  mp_size_t s;
108  mpz_t ds; mpz_init (ds);
109  mpz_urandomb (ds, rands, 32);
110  s = mpz_get_ui (ds) % (max + 1);
111  MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x));
112  MPN_ZERO (PTR(x), s);
113  SIZ(x) += s;
114  mpz_clear (ds);
115}
116
117void
118dump_abort (mpf_t a, mpf_t b, int cmp_prec, int lshift1, int lshift2, int hibits, int want, long test)
119{
120  printf ("ERROR in test %ld\n", test);
121  printf ("want %d got %d from mpf_eq\n", want, 1-want);
122  printf ("cmp_prec = %d\n", cmp_prec);
123  printf ("lshift1 = %d\n", lshift1);
124  printf ("lshift2 = %d\n", lshift2);
125  printf ("hibits = %d\n", hibits);
126  hexdump (a); puts ("");
127  hexdump (b); puts ("");
128  abort ();
129}
130
131void
132hexdump (mpf_t x)
133{
134  mp_size_t i;
135  for (i = ABSIZ(x) - 1; i >= 0; i--)
136    {
137      gmp_printf ("%0*MX", SZ, PTR(x)[i]);
138      if (i != 0)
139	printf (" ");
140    }
141}
142