1 /* test mpz_congruent_2exp_p */ 2 3 /* 4 Copyright 2001 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 http://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 87 }; 88 89 mpz_t a, c; 90 int i; 91 92 mpz_init (a); 93 mpz_init (c); 94 95 for (i = 0; i < numberof (data); i++) 96 { 97 mpz_set_str_or_abort (a, data[i].a, 0); 98 mpz_set_str_or_abort (c, data[i].c, 0); 99 check_one (a, c, data[i].d, data[i].want); 100 } 101 102 mpz_clear (a); 103 mpz_clear (c); 104 } 105 106 107 void 108 check_random (int argc, char *argv[]) 109 { 110 gmp_randstate_ptr rands = RANDS; 111 unsigned long d; 112 mpz_t a, c, ra, rc; 113 int i; 114 int want; 115 int reps = 5000; 116 117 if (argc >= 2) 118 reps = atoi (argv[1]); 119 120 mpz_init (a); 121 mpz_init (c); 122 mpz_init (ra); 123 mpz_init (rc); 124 125 for (i = 0; i < reps; i++) 126 { 127 mpz_errandomb (a, rands, 8*GMP_LIMB_BITS); 128 mpz_errandomb (c, rands, 8*GMP_LIMB_BITS); 129 d = urandom() % (8*GMP_LIMB_BITS); 130 131 mpz_mul_2exp (a, a, urandom() % (2*GMP_LIMB_BITS)); 132 mpz_mul_2exp (c, c, urandom() % (2*GMP_LIMB_BITS)); 133 134 mpz_negrandom (a, rands); 135 mpz_negrandom (c, rands); 136 137 mpz_fdiv_r_2exp (ra, a, d); 138 mpz_fdiv_r_2exp (rc, c, d); 139 140 want = (mpz_cmp (ra, rc) == 0); 141 check_one (a, c, d, want); 142 143 mpz_sub (ra, ra, rc); 144 mpz_sub (a, a, ra); 145 check_one (a, c, d, 1); 146 } 147 148 mpz_clear (a); 149 mpz_clear (c); 150 mpz_clear (ra); 151 mpz_clear (rc); 152 } 153 154 155 int 156 main (int argc, char *argv[]) 157 { 158 tests_start (); 159 160 check_data (); 161 check_random (argc, argv); 162 163 tests_end (); 164 exit (0); 165 } 166