1/* test mpz_congruent_2exp_p */ 2 3/* 4Copyright 2001 Free Software Foundation, Inc. 5 6This file is part of the GNU MP Library. 7 8The GNU MP Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MP Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MP Library. 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 28void 29check_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 69void 70check_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 107void 108check_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 155int 156main (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