t-eq.c revision 1.1.1.2
1/* Test mpf_eq. 2 3Copyright 2009, 2012 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library test suite. 6 7The GNU MP Library test suite is free software; you can redistribute it 8and/or modify it under the terms of the GNU General Public License as 9published by the Free Software Foundation; either version 3 of the License, 10or (at your option) any later version. 11 12The GNU MP Library test suite is distributed in the hope that it will be 13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15Public License for more details. 16 17You should have received a copy of the GNU General Public License along with 18the GNU MP Library test suite. 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 33void 34check_data (void) 35{ 36 static const struct 37 { 38 struct { 39 int exp, size; 40 mp_limb_t d[10]; 41 } x, y; 42 mp_bitcnt_t bits; 43 int want; 44 45 } data[] = { 46 { { 0, 0, { 0 } }, { 0, 0, { 0 } }, 0, 1 }, 47 48 { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 0, 1 }, 49 { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 17, 1 }, 50 { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 4711, 1 }, 51 52 { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 0, 1 }, 53 { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 2, 1 }, 54 { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 3, 0 }, 55 56 { { 0, 0, { 0 } }, { 0, 1, { 1 } }, 0, 0 }, 57 { { 0, 1, { 1 } }, { 0,-1 ,{ 1 } }, 0, 0 }, 58 { { 1, 1, { 1 } }, { 0, 1, { 1 } }, 0, 0 }, 59 60 { { 0, 1, { 8 } }, { 0, 1, { 4 } }, 0, 0 }, 61 62 { { 0, 2, { 0, 3 } }, { 0, 1, { 3 } }, 1000, 1 }, 63 }; 64 65 mpf_t x, y; 66 int got, got_swapped; 67 int i; 68 mp_trace_base = 16; 69 70 for (i = 0; i < numberof (data); i++) 71 { 72 PTR(x) = (mp_ptr) data[i].x.d; 73 SIZ(x) = data[i].x.size; 74 EXP(x) = data[i].x.exp; 75 PREC(x) = numberof (data[i].x.d); 76 MPF_CHECK_FORMAT (x); 77 78 PTR(y) = (mp_ptr) data[i].y.d; 79 SIZ(y) = data[i].y.size; 80 EXP(y) = data[i].y.exp; 81 PREC(y) = numberof (data[i].y.d); 82 MPF_CHECK_FORMAT (y); 83 84 got = mpf_eq (x, y, data[i].bits); 85 got_swapped = mpf_eq (y, x, data[i].bits); 86 87 if (got != got_swapped || got != data[i].want) 88 { 89 printf ("check_data() wrong reault at data[%d]\n", i); 90 mpf_trace ("x ", x); 91 mpf_trace ("y ", y); 92 printf ("got %d\n", got); 93 printf ("got_swapped %d\n", got_swapped); 94 printf ("want %d\n", data[i].want); 95 abort (); 96 } 97 } 98} 99 100void 101check_random (long reps) 102{ 103 unsigned long test; 104 gmp_randstate_ptr rands = RANDS; 105 mpf_t a, b, x; 106 mpz_t ds; 107 int hibits, lshift1, lshift2; 108 int xtra; 109 110#define HIBITS 10 111#define LSHIFT1 10 112#define LSHIFT2 10 113 114 mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2)); 115 116 mpz_init (ds); 117 mpf_inits (a, b, x, NULL); 118 119 for (test = 0; test < reps; test++) 120 { 121 mpz_urandomb (ds, rands, HIBITS); 122 hibits = mpz_get_ui (ds) + 1; 123 mpz_urandomb (ds, rands, hibits); 124 mpz_setbit (ds, hibits - 1); /* make sure msb is set */ 125 mpf_set_z (a, ds); 126 mpf_set_z (b, ds); 127 128 mpz_urandomb (ds, rands, LSHIFT1); 129 lshift1 = mpz_get_ui (ds); 130 mpf_mul_2exp (a, a, lshift1 + 1); 131 mpf_mul_2exp (b, b, lshift1 + 1); 132 mpf_add_ui (a, a, 1); /* make a one-bit difference */ 133 134 mpz_urandomb (ds, rands, LSHIFT2); 135 lshift2 = mpz_get_ui (ds); 136 mpf_mul_2exp (a, a, lshift2); 137 mpf_mul_2exp (b, b, lshift2); 138 mpz_urandomb (ds, rands, lshift2); 139 mpf_set_z (x, ds); 140 mpf_add (a, a, x); 141 mpf_add (b, b, x); 142 143 insert_random_low_zero_limbs (a, rands); 144 insert_random_low_zero_limbs (b, rands); 145 146 if (mpf_eq (a, b, lshift1 + hibits) == 0 || 147 mpf_eq (b, a, lshift1 + hibits) == 0) 148 { 149 dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test); 150 } 151 for (xtra = 1; xtra < 100; xtra++) 152 if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0 || 153 mpf_eq (b, a, lshift1 + hibits + xtra) != 0) 154 { 155 dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test); 156 } 157 } 158 159 mpf_clears (a, b, x, NULL); 160 mpz_clear (ds); 161} 162 163void 164insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands) 165{ 166 mp_size_t max = PREC(x) - SIZ(x); 167 mp_size_t s; 168 mpz_t ds; mpz_init (ds); 169 mpz_urandomb (ds, rands, 32); 170 s = mpz_get_ui (ds) % (max + 1); 171 MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x)); 172 MPN_ZERO (PTR(x), s); 173 SIZ(x) += s; 174 mpz_clear (ds); 175} 176 177void 178dump_abort (mpf_t a, mpf_t b, int cmp_prec, int lshift1, int lshift2, int hibits, int want, long test) 179{ 180 printf ("ERROR in test %ld\n", test); 181 printf ("want %d got %d from mpf_eq\n", want, 1-want); 182 printf ("cmp_prec = %d\n", cmp_prec); 183 printf ("lshift1 = %d\n", lshift1); 184 printf ("lshift2 = %d\n", lshift2); 185 printf ("hibits = %d\n", hibits); 186 hexdump (a); puts (""); 187 hexdump (b); puts (""); 188 abort (); 189} 190 191void 192hexdump (mpf_t x) 193{ 194 mp_size_t i; 195 for (i = ABSIZ(x) - 1; i >= 0; i--) 196 { 197 gmp_printf ("%0*MX", SZ, PTR(x)[i]); 198 if (i != 0) 199 printf (" "); 200 } 201} 202 203int 204main (int argc, char *argv[]) 205{ 206 long reps = 10000; 207 208 if (argc == 2) 209 reps = strtol (argv[1], 0, 0); 210 211 tests_start (); 212 213 check_data (); 214 check_random (reps); 215 216 tests_end (); 217 exit (0); 218} 219