github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-cong_2exp.c (about) 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.h" 24 #include "gmp-impl.h" 25 #include "tests.h" 26 27 28 void 29 check_one (mpz_srcptr a, mpz_srcptr c, unsigned long d, int want) 30 { 31 mpz_t diff, d2exp; 32 int got; 33 int swap; 34 35 for (swap = 0; swap <= 1; swap++) 36 { 37 got = (mpz_congruent_2exp_p (a, c, d) != 0); 38 if (want != got) 39 { 40 mpz_init (diff); 41 mpz_init (d2exp); 42 43 mpz_sub (diff, a, c); 44 mpz_set_ui (d2exp, 1L); 45 mpz_mul_2exp (d2exp, d2exp, d); 46 47 printf ("mpz_congruent_2exp_p wrong\n"); 48 printf (" expected %d got %d\n", want, got); 49 mpz_trace (" a", a); 50 mpz_trace (" c", c); 51 mpz_trace (" a-c", diff); 52 mpz_trace (" 2^d", d2exp); 53 printf (" d=%lu\n", d); 54 55 mp_trace_base = -16; 56 mpz_trace (" a", a); 57 mpz_trace (" c", c); 58 mpz_trace (" a-c", diff); 59 mpz_trace (" 2^d", d2exp); 60 printf (" d=0x%lX\n", d); 61 abort (); 62 } 63 64 MPZ_SRCPTR_SWAP (a, c); 65 } 66 } 67 68 69 void 70 check_data (void) 71 { 72 static const struct { 73 const char *a; 74 const char *c; 75 unsigned long d; 76 int want; 77 78 } data[] = { 79 80 /* anything is congruent mod 1 */ 81 { "0", "0", 0, 1 }, 82 { "1", "0", 0, 1 }, 83 { "0", "1", 0, 1 }, 84 { "123", "-456", 0, 1 }, 85 { "0x123456789123456789", "0x987654321987654321", 0, 1 }, 86 { "0xfffffffffffffffffffffffffffffff7", "-0x9", 129, 0 }, 87 { "0xfffffffffffffffffffffffffffffff6", "-0xa", 128, 1 }, 88 89 }; 90 91 mpz_t a, c; 92 int i; 93 94 mpz_init (a); 95 mpz_init (c); 96 97 for (i = 0; i < numberof (data); i++) 98 { 99 mpz_set_str_or_abort (a, data[i].a, 0); 100 mpz_set_str_or_abort (c, data[i].c, 0); 101 check_one (a, c, data[i].d, data[i].want); 102 } 103 104 mpz_clear (a); 105 mpz_clear (c); 106 } 107 108 109 void 110 check_random (int reps) 111 { 112 gmp_randstate_ptr rands = RANDS; 113 unsigned long d; 114 mpz_t a, c, ra, rc; 115 int i; 116 117 mpz_init (a); 118 mpz_init (c); 119 mpz_init (ra); 120 mpz_init (rc); 121 122 for (i = 0; i < reps; i++) 123 { 124 mpz_errandomb (a, rands, 8*GMP_LIMB_BITS); 125 mpz_errandomb (c, rands, 8*GMP_LIMB_BITS); 126 d = urandom() % (8*GMP_LIMB_BITS); 127 128 mpz_mul_2exp (a, a, urandom() % (2*GMP_LIMB_BITS)); 129 mpz_mul_2exp (c, c, urandom() % (2*GMP_LIMB_BITS)); 130 131 mpz_negrandom (a, rands); 132 mpz_negrandom (c, rands); 133 134 mpz_fdiv_r_2exp (ra, a, d); 135 mpz_fdiv_r_2exp (rc, c, d); 136 137 mpz_sub (ra, ra, rc); 138 if (mpz_cmp_ui (ra, 0) != 0) 139 { 140 check_one (a, c, d, 0); 141 mpz_sub (a, a, ra); 142 } 143 check_one (a, c, d, 1); 144 if (d != 0) 145 { 146 mpz_combit (a, urandom() % d); 147 check_one (a, c, d, 0); 148 } 149 } 150 151 mpz_clear (a); 152 mpz_clear (c); 153 mpz_clear (ra); 154 mpz_clear (rc); 155 } 156 157 void 158 check_random_bits (int reps) 159 { 160 mp_bitcnt_t ea, ec, en, d; 161 mp_bitcnt_t m = 10 * GMP_LIMB_BITS; 162 mpz_t a, c; 163 int i; 164 165 mpz_init2 (a, m + 1); 166 mpz_init2 (c, m); 167 168 for (i = 0; i < reps; i++) 169 { 170 d = urandom() % m; 171 ea = urandom() % m; 172 ec = urandom() % m; 173 en = urandom() % m; 174 175 mpz_set_ui (c, 0); 176 mpz_setbit (c, en); 177 178 mpz_set_ui (a, 0); 179 mpz_setbit (a, ec); 180 mpz_sub (c , a, c); 181 182 mpz_set_ui (a, 0); 183 mpz_setbit (a, ea); 184 mpz_add (a , a, c); 185 186 check_one (a, c, d, ea >= d); 187 } 188 189 mpz_clear (a); 190 mpz_clear (c); 191 } 192 193 194 int 195 main (int argc, char *argv[]) 196 { 197 int reps = 5000; 198 199 tests_start (); 200 TESTS_REPS (reps, argv, argc); 201 202 check_data (); 203 check_random (reps); 204 check_random_bits (reps); 205 206 tests_end (); 207 exit (0); 208 }