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