1 /* test mpz_congruent_2exp_p */ 2 3 /* 4 Copyright 2001, 2013 Free Software Foundation, Inc. 5 6 This file is part of the GNU MP Library test suite. 7 8 The GNU MP Library test suite is free software; you can redistribute it 9 and/or modify it under the terms of the GNU General Public License as 10 published by the Free Software Foundation; either version 3 of the License, 11 or (at your option) any later version. 12 13 The GNU MP Library test suite is distributed in the hope that it will be 14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 16 Public License for more details. 17 18 You should have received a copy of the GNU General Public License along with 19 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 20 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include "gmp-impl.h" 24 #include "tests.h" 25 26 27 void 28 check_one (mpz_srcptr a, mpz_srcptr c, unsigned long d, int want) 29 { 30 mpz_t diff, d2exp; 31 int got; 32 int swap; 33 34 for (swap = 0; swap <= 1; swap++) 35 { 36 got = (mpz_congruent_2exp_p (a, c, d) != 0); 37 if (want != got) 38 { 39 mpz_init (diff); 40 mpz_init (d2exp); 41 42 mpz_sub (diff, a, c); 43 mpz_set_ui (d2exp, 1L); 44 mpz_mul_2exp (d2exp, d2exp, d); 45 46 printf ("mpz_congruent_2exp_p wrong\n"); 47 printf (" expected %d got %d\n", want, got); 48 mpz_trace (" a", a); 49 mpz_trace (" c", c); 50 mpz_trace (" a-c", diff); 51 mpz_trace (" 2^d", d2exp); 52 printf (" d=%lu\n", d); 53 54 mp_trace_base = -16; 55 mpz_trace (" a", a); 56 mpz_trace (" c", c); 57 mpz_trace (" a-c", diff); 58 mpz_trace (" 2^d", d2exp); 59 printf (" d=0x%lX\n", d); 60 abort (); 61 } 62 63 MPZ_SRCPTR_SWAP (a, c); 64 } 65 } 66 67 68 void 69 check_data (void) 70 { 71 static const struct { 72 const char *a; 73 const char *c; 74 unsigned long d; 75 int want; 76 77 } data[] = { 78 79 /* anything is congruent mod 1 */ 80 { "0", "0", 0, 1 }, 81 { "1", "0", 0, 1 }, 82 { "0", "1", 0, 1 }, 83 { "123", "-456", 0, 1 }, 84 { "0x123456789123456789", "0x987654321987654321", 0, 1 }, 85 { "0xfffffffffffffffffffffffffffffff7", "-0x9", 129, 0 }, 86 { "0xfffffffffffffffffffffffffffffff6", "-0xa", 128, 1 }, 87 88 }; 89 90 mpz_t a, c; 91 int i; 92 93 mpz_init (a); 94 mpz_init (c); 95 96 for (i = 0; i < numberof (data); i++) 97 { 98 mpz_set_str_or_abort (a, data[i].a, 0); 99 mpz_set_str_or_abort (c, data[i].c, 0); 100 check_one (a, c, data[i].d, data[i].want); 101 } 102 103 mpz_clear (a); 104 mpz_clear (c); 105 } 106 107 108 void 109 check_random (int reps) 110 { 111 gmp_randstate_ptr rands = RANDS; 112 unsigned long d; 113 mpz_t a, c, ra, rc; 114 int i; 115 116 mpz_init (a); 117 mpz_init (c); 118 mpz_init (ra); 119 mpz_init (rc); 120 121 for (i = 0; i < reps; i++) 122 { 123 mpz_errandomb (a, rands, 8*GMP_LIMB_BITS); 124 mpz_errandomb (c, rands, 8*GMP_LIMB_BITS); 125 d = urandom() % (8*GMP_LIMB_BITS); 126 127 mpz_mul_2exp (a, a, urandom() % (2*GMP_LIMB_BITS)); 128 mpz_mul_2exp (c, c, urandom() % (2*GMP_LIMB_BITS)); 129 130 mpz_negrandom (a, rands); 131 mpz_negrandom (c, rands); 132 133 mpz_fdiv_r_2exp (ra, a, d); 134 mpz_fdiv_r_2exp (rc, c, d); 135 136 mpz_sub (ra, ra, rc); 137 if (mpz_cmp_ui (ra, 0) != 0) 138 { 139 check_one (a, c, d, 0); 140 mpz_sub (a, a, ra); 141 } 142 check_one (a, c, d, 1); 143 if (d != 0) 144 { 145 mpz_combit (a, urandom() % d); 146 check_one (a, c, d, 0); 147 } 148 } 149 150 mpz_clear (a); 151 mpz_clear (c); 152 mpz_clear (ra); 153 mpz_clear (rc); 154 } 155 156 void 157 check_random_bits (int reps) 158 { 159 mp_bitcnt_t ea, ec, en, d; 160 mp_bitcnt_t m = 10 * GMP_LIMB_BITS; 161 mpz_t a, c; 162 int i; 163 164 mpz_init2 (a, m + 1); 165 mpz_init2 (c, m); 166 167 for (i = 0; i < reps; i++) 168 { 169 d = urandom() % m; 170 ea = urandom() % m; 171 ec = urandom() % m; 172 en = urandom() % m; 173 174 mpz_set_ui (c, 0); 175 mpz_setbit (c, en); 176 177 mpz_set_ui (a, 0); 178 mpz_setbit (a, ec); 179 mpz_sub (c , a, c); 180 181 mpz_set_ui (a, 0); 182 mpz_setbit (a, ea); 183 mpz_add (a , a, c); 184 185 check_one (a, c, d, ea >= d); 186 } 187 188 mpz_clear (a); 189 mpz_clear (c); 190 } 191 192 193 int 194 main (int argc, char *argv[]) 195 { 196 int reps = 5000; 197 198 tests_start (); 199 TESTS_REPS (reps, argv, argc); 200 201 check_data (); 202 check_random (reps); 203 check_random_bits (reps); 204 205 tests_end (); 206 exit (0); 207 } 208