github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpf/t-eq.c (about) 1 /* Test mpf_eq. 2 3 Copyright 2009, 2012 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library test suite. 6 7 The GNU MP Library test suite is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 3 of the License, 10 or (at your option) any later version. 11 12 The GNU MP Library test suite is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 Public License for more details. 16 17 You should have received a copy of the GNU General Public License along with 18 the GNU MP Library test suite. If not, see https://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 29 void insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr); 30 void dump_abort (mpf_t, mpf_t, int, int, int, int, int, long); 31 void hexdump (mpf_t); 32 33 void 34 check_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 result 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 100 void 101 check_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 163 void 164 insert_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 177 void 178 dump_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 191 void 192 hexdump (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 203 int 204 main (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 }