github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-divis.c (about) 1 /* test mpz_divisible_p and mpz_divisible_ui_p 2 3 Copyright 2001, 2009 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 28 void 29 check_one (mpz_srcptr a, mpz_srcptr d, int want) 30 { 31 int got; 32 33 if (mpz_fits_ulong_p (d)) 34 { 35 unsigned long u = mpz_get_ui (d); 36 got = (mpz_divisible_ui_p (a, u) != 0); 37 if (want != got) 38 { 39 printf ("mpz_divisible_ui_p wrong\n"); 40 printf (" expected %d got %d\n", want, got); 41 mpz_trace (" a", a); 42 printf (" d=%lu\n", u); 43 mp_trace_base = -16; 44 mpz_trace (" a", a); 45 printf (" d=0x%lX\n", u); 46 abort (); 47 } 48 } 49 50 got = (mpz_divisible_p (a, d) != 0); 51 if (want != got) 52 { 53 printf ("mpz_divisible_p wrong\n"); 54 printf (" expected %d got %d\n", want, got); 55 mpz_trace (" a", a); 56 mpz_trace (" d", d); 57 mp_trace_base = -16; 58 mpz_trace (" a", a); 59 mpz_trace (" d", d); 60 abort (); 61 } 62 } 63 64 void 65 check_data (void) 66 { 67 static const struct { 68 const char *a; 69 const char *d; 70 int want; 71 72 } data[] = { 73 74 { "0", "0", 1 }, 75 { "17", "0", 0 }, 76 { "0", "1", 1 }, 77 { "123", "1", 1 }, 78 { "-123", "1", 1 }, 79 80 { "0", "2", 1 }, 81 { "1", "2", 0 }, 82 { "2", "2", 1 }, 83 { "-2", "2", 1 }, 84 { "0x100000000000000000000000000000000", "2", 1 }, 85 { "0x100000000000000000000000000000001", "2", 0 }, 86 87 { "0x3333333333333333", "3", 1 }, 88 { "0x3333333333333332", "3", 0 }, 89 { "0x33333333333333333333333333333333", "3", 1 }, 90 { "0x33333333333333333333333333333332", "3", 0 }, 91 92 /* divisor changes from 2 to 1 limb after stripping 2s */ 93 { "0x3333333300000000", "0x180000000", 1 }, 94 { "0x33333333333333330000000000000000", "0x18000000000000000", 1 }, 95 { "0x133333333333333330000000000000000", "0x18000000000000000", 0 }, 96 }; 97 98 mpz_t a, d; 99 int i; 100 101 mpz_init (a); 102 mpz_init (d); 103 104 for (i = 0; i < numberof (data); i++) 105 { 106 mpz_set_str_or_abort (a, data[i].a, 0); 107 mpz_set_str_or_abort (d, data[i].d, 0); 108 check_one (a, d, data[i].want); 109 } 110 111 mpz_clear (a); 112 mpz_clear (d); 113 } 114 115 void 116 check_random (int reps) 117 { 118 gmp_randstate_ptr rands = RANDS; 119 mpz_t a, d, r; 120 int i; 121 int want; 122 123 mpz_init (a); 124 mpz_init (d); 125 mpz_init (r); 126 127 for (i = 0; i < reps; i++) 128 { 129 mpz_erandomb (a, rands, 1 << 19); 130 mpz_erandomb_nonzero (d, rands, 1 << 18); 131 132 mpz_fdiv_r (r, a, d); 133 134 want = (mpz_sgn (r) == 0); 135 check_one (a, d, want); 136 137 mpz_sub (a, a, r); 138 check_one (a, d, 1); 139 140 if (mpz_cmpabs_ui (d, 1L) == 0) 141 continue; 142 143 mpz_add_ui (a, a, 1L); 144 check_one (a, d, 0); 145 } 146 147 mpz_clear (a); 148 mpz_clear (d); 149 mpz_clear (r); 150 } 151 152 153 int 154 main (int argc, char *argv[]) 155 { 156 int reps = 100; 157 158 tests_start (); 159 160 if (argc == 2) 161 reps = atoi (argv[1]); 162 163 check_data (); 164 check_random (reps); 165 166 tests_end (); 167 exit (0); 168 }