xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-divis.c (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
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 http://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 }
169