xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-divis.c (revision 4fee23f98c45552038ad6b5bd05124a41302fb01)
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.
6 
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library.  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",    "1", 1 },
75     { "123",  "1", 1 },
76     { "-123", "1", 1 },
77 
78     { "0",  "2", 1 },
79     { "1",  "2", 0 },
80     { "2",  "2", 1 },
81     { "-2", "2", 1 },
82     { "0x100000000000000000000000000000000", "2", 1 },
83     { "0x100000000000000000000000000000001", "2", 0 },
84 
85     { "0x3333333333333333", "3", 1 },
86     { "0x3333333333333332", "3", 0 },
87     { "0x33333333333333333333333333333333", "3", 1 },
88     { "0x33333333333333333333333333333332", "3", 0 },
89 
90     /* divisor changes from 2 to 1 limb after stripping 2s */
91     {          "0x3333333300000000",         "0x180000000",         1 },
92     {  "0x33333333333333330000000000000000", "0x18000000000000000", 1 },
93     { "0x133333333333333330000000000000000", "0x18000000000000000", 0 },
94   };
95 
96   mpz_t   a, d;
97   int     i;
98 
99   mpz_init (a);
100   mpz_init (d);
101 
102   for (i = 0; i < numberof (data); i++)
103     {
104       mpz_set_str_or_abort (a, data[i].a, 0);
105       mpz_set_str_or_abort (d, data[i].d, 0);
106       check_one (a, d, data[i].want);
107     }
108 
109   mpz_clear (a);
110   mpz_clear (d);
111 }
112 
113 void
114 check_random (int reps)
115 {
116   gmp_randstate_ptr rands = RANDS;
117   mpz_t   a, d, r;
118   int     i;
119   int     want;
120 
121   mpz_init (a);
122   mpz_init (d);
123   mpz_init (r);
124 
125   for (i = 0; i < reps; i++)
126     {
127       mpz_erandomb (a, rands, 1 << 19);
128       mpz_erandomb_nonzero (d, rands, 1 << 18);
129 
130       mpz_fdiv_r (r, a, d);
131 
132       want = (mpz_sgn (r) == 0);
133       check_one (a, d, want);
134 
135       mpz_sub (a, a, r);
136       check_one (a, d, 1);
137 
138       if (mpz_cmpabs_ui (d, 1L) == 0)
139         continue;
140 
141       mpz_add_ui (a, a, 1L);
142       check_one (a, d, 0);
143     }
144 
145   mpz_clear (a);
146   mpz_clear (d);
147   mpz_clear (r);
148 }
149 
150 
151 int
152 main (int argc, char *argv[])
153 {
154   int  reps = 100;
155 
156   tests_start ();
157 
158   if (argc == 2)
159     reps = atoi (argv[1]);
160 
161   check_data ();
162   check_random (reps);
163 
164   tests_end ();
165   exit (0);
166 }
167