1415SN/A/* Test mpf_eq. 2553SN/A 3415SN/ACopyright 2009, 2012 Free Software Foundation, Inc. 4415SN/A 5415SN/AThis file is part of the GNU MP Library test suite. 6415SN/A 7553SN/AThe GNU MP Library test suite is free software; you can redistribute it 8415SN/Aand/or modify it under the terms of the GNU General Public License as 9553SN/Apublished by the Free Software Foundation; either version 3 of the License, 10415SN/Aor (at your option) any later version. 11415SN/A 12415SN/AThe GNU MP Library test suite is distributed in the hope that it will be 13415SN/Auseful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14415SN/AMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15415SN/APublic License for more details. 16415SN/A 17415SN/AYou should have received a copy of the GNU General Public License along with 18415SN/Athe GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19415SN/A 20415SN/A#include <stdio.h> 21553SN/A#include <stdlib.h> 22553SN/A 23553SN/A#include "gmp-impl.h" 24415SN/A#include "tests.h" 25415SN/A 26415SN/A#define SZ (2 * sizeof(mp_limb_t)) 27415SN/A 28415SN/Avoid insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr); 29415SN/Avoid dump_abort (mpf_t, mpf_t, int, int, int, int, int, long); 30415SN/Avoid hexdump (mpf_t); 31415SN/A 32415SN/Avoid 33415SN/Acheck_data (void) 34415SN/A{ 35415SN/A static const struct 36415SN/A { 37415SN/A struct { 38415SN/A int exp, size; 39415SN/A mp_limb_t d[10]; 40415SN/A } x, y; 41415SN/A mp_bitcnt_t bits; 422601Sjlahoda int want; 432601Sjlahoda 442601Sjlahoda } data[] = { 45415SN/A { { 0, 0, { 0 } }, { 0, 0, { 0 } }, 0, 1 }, 46580SN/A 47415SN/A { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 0, 1 }, 48415SN/A { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 17, 1 }, 49415SN/A { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 4711, 1 }, 50415SN/A 51415SN/A { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 0, 1 }, 52415SN/A { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 2, 1 }, 53415SN/A { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 3, 0 }, 54415SN/A 55415SN/A { { 0, 0, { 0 } }, { 0, 1, { 1 } }, 0, 0 }, 56415SN/A { { 0, 1, { 1 } }, { 0,-1 ,{ 1 } }, 0, 0 }, 57415SN/A { { 1, 1, { 1 } }, { 0, 1, { 1 } }, 0, 0 }, 58415SN/A 59415SN/A { { 0, 1, { 8 } }, { 0, 1, { 4 } }, 0, 0 }, 60415SN/A 61415SN/A { { 0, 2, { 0, 3 } }, { 0, 1, { 3 } }, 1000, 1 }, 62415SN/A }; 63415SN/A 64415SN/A mpf_t x, y; 652601Sjlahoda int got, got_swapped; 66415SN/A int i; 67415SN/A mp_trace_base = 16; 68415SN/A 69415SN/A for (i = 0; i < numberof (data); i++) 70415SN/A { 71415SN/A PTR(x) = (mp_ptr) data[i].x.d; 72415SN/A SIZ(x) = data[i].x.size; 73415SN/A EXP(x) = data[i].x.exp; 74415SN/A PREC(x) = numberof (data[i].x.d); 75415SN/A MPF_CHECK_FORMAT (x); 762601Sjlahoda 77415SN/A PTR(y) = (mp_ptr) data[i].y.d; 78415SN/A SIZ(y) = data[i].y.size; 79415SN/A EXP(y) = data[i].y.exp; 80415SN/A PREC(y) = numberof (data[i].y.d); 812601Sjlahoda MPF_CHECK_FORMAT (y); 82415SN/A 832229SN/A got = mpf_eq (x, y, data[i].bits); 842229SN/A got_swapped = mpf_eq (y, x, data[i].bits); 852229SN/A 86415SN/A if (got != got_swapped || got != data[i].want) 87415SN/A { 88415SN/A printf ("check_data() wrong result at data[%d]\n", i); 89415SN/A mpf_trace ("x ", x); 90 mpf_trace ("y ", y); 91 printf ("got %d\n", got); 92 printf ("got_swapped %d\n", got_swapped); 93 printf ("want %d\n", data[i].want); 94 abort (); 95 } 96 } 97} 98 99void 100check_random (long reps) 101{ 102 unsigned long test; 103 gmp_randstate_ptr rands = RANDS; 104 mpf_t a, b, x; 105 mpz_t ds; 106 int hibits, lshift1, lshift2; 107 int xtra; 108 109#define HIBITS 10 110#define LSHIFT1 10 111#define LSHIFT2 10 112 113 mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2)); 114 115 mpz_init (ds); 116 mpf_inits (a, b, x, NULL); 117 118 for (test = 0; test < reps; test++) 119 { 120 mpz_urandomb (ds, rands, HIBITS); 121 hibits = mpz_get_ui (ds) + 1; 122 mpz_urandomb (ds, rands, hibits); 123 mpz_setbit (ds, hibits - 1); /* make sure msb is set */ 124 mpf_set_z (a, ds); 125 mpf_set_z (b, ds); 126 127 mpz_urandomb (ds, rands, LSHIFT1); 128 lshift1 = mpz_get_ui (ds); 129 mpf_mul_2exp (a, a, lshift1 + 1); 130 mpf_mul_2exp (b, b, lshift1 + 1); 131 mpf_add_ui (a, a, 1); /* make a one-bit difference */ 132 133 mpz_urandomb (ds, rands, LSHIFT2); 134 lshift2 = mpz_get_ui (ds); 135 mpf_mul_2exp (a, a, lshift2); 136 mpf_mul_2exp (b, b, lshift2); 137 mpz_urandomb (ds, rands, lshift2); 138 mpf_set_z (x, ds); 139 mpf_add (a, a, x); 140 mpf_add (b, b, x); 141 142 insert_random_low_zero_limbs (a, rands); 143 insert_random_low_zero_limbs (b, rands); 144 145 if (mpf_eq (a, b, lshift1 + hibits) == 0 || 146 mpf_eq (b, a, lshift1 + hibits) == 0) 147 { 148 dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test); 149 } 150 for (xtra = 1; xtra < 100; xtra++) 151 if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0 || 152 mpf_eq (b, a, lshift1 + hibits + xtra) != 0) 153 { 154 dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test); 155 } 156 } 157 158 mpf_clears (a, b, x, NULL); 159 mpz_clear (ds); 160} 161 162void 163insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands) 164{ 165 mp_size_t max = PREC(x) - SIZ(x); 166 mp_size_t s; 167 mpz_t ds; mpz_init (ds); 168 mpz_urandomb (ds, rands, 32); 169 s = mpz_get_ui (ds) % (max + 1); 170 MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x)); 171 MPN_ZERO (PTR(x), s); 172 SIZ(x) += s; 173 mpz_clear (ds); 174} 175 176void 177dump_abort (mpf_t a, mpf_t b, int cmp_prec, int lshift1, int lshift2, int hibits, int want, long test) 178{ 179 printf ("ERROR in test %ld\n", test); 180 printf ("want %d got %d from mpf_eq\n", want, 1-want); 181 printf ("cmp_prec = %d\n", cmp_prec); 182 printf ("lshift1 = %d\n", lshift1); 183 printf ("lshift2 = %d\n", lshift2); 184 printf ("hibits = %d\n", hibits); 185 hexdump (a); puts (""); 186 hexdump (b); puts (""); 187 abort (); 188} 189 190void 191hexdump (mpf_t x) 192{ 193 mp_size_t i; 194 for (i = ABSIZ(x) - 1; i >= 0; i--) 195 { 196 gmp_printf ("%0*MX", SZ, PTR(x)[i]); 197 if (i != 0) 198 printf (" "); 199 } 200} 201 202int 203main (int argc, char *argv[]) 204{ 205 long reps = 10000; 206 207 if (argc == 2) 208 reps = strtol (argv[1], 0, 0); 209 210 tests_start (); 211 212 check_data (); 213 check_random (reps); 214 215 tests_end (); 216 exit (0); 217} 218