1/* Tests of mpz_scan0 and mpz_scan1.
2
3Copyright 2000-2003 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include "gmp-impl.h"
23#include "tests.h"
24
25
26unsigned long
27refmpz_scan (mpz_srcptr z, unsigned long i, int sought)
28{
29  unsigned long  z_bits = (unsigned long) ABSIZ(z) * GMP_NUMB_BITS;
30
31  do
32    {
33      if (mpz_tstbit (z, i) == sought)
34        return i;
35      i++;
36    }
37  while (i <= z_bits);
38
39  return ULONG_MAX;
40}
41
42unsigned long
43refmpz_scan0 (mpz_srcptr z, unsigned long starting_bit)
44{
45  return refmpz_scan (z, starting_bit, 0);
46}
47
48unsigned long
49refmpz_scan1 (mpz_srcptr z, unsigned long starting_bit)
50{
51  return refmpz_scan (z, starting_bit, 1);
52}
53
54
55void
56check_ref (void)
57{
58  static const int offset[] = {
59    -2, -1, 0, 1, 2, 3
60  };
61
62  mpz_t          z;
63  int            test, neg, sought, oindex, o;
64  mp_size_t      size, isize;
65  unsigned long  start, got, want;
66
67  mpz_init (z);
68  for (test = 0; test < 5; test++)
69    {
70      for (size = 0; size < 5; size++)
71        {
72          mpz_random2 (z, size);
73
74          for (neg = 0; neg <= 1; neg++)
75            {
76              if (neg)
77                mpz_neg (z, z);
78
79              for (isize = 0; isize <= size; isize++)
80                {
81                  for (oindex = 0; oindex < numberof (offset); oindex++)
82                    {
83                      o = offset[oindex];
84                      if ((int) isize*GMP_NUMB_BITS < -o)
85                        continue;  /* start would be negative */
86
87                      start = isize*GMP_NUMB_BITS + o;
88
89                      for (sought = 0; sought <= 1; sought++)
90                        {
91                          if (sought == 0)
92                            {
93                              got = mpz_scan0 (z, start);
94                              want = refmpz_scan0 (z, start);
95                            }
96                          else
97                            {
98                              got = mpz_scan1 (z, start);
99                              want = refmpz_scan1 (z, start);
100                            }
101
102                          if (got != want)
103                            {
104                              printf ("wrong at test=%d, size=%ld, neg=%d, start=%lu, sought=%d\n",
105                                      test, size, neg, start, sought);
106                              printf ("   z 0x");
107                              mpz_out_str (stdout, -16, z);
108                              printf ("\n");
109                              printf ("   got=%lu, want=%lu\n", got, want);
110                              exit (1);
111                            }
112                        }
113                    }
114                }
115            }
116        }
117    }
118  mpz_clear (z);
119}
120
121
122int
123main (int argc, char *argv[])
124{
125  tests_start ();
126
127  check_ref ();
128
129  tests_end ();
130  exit (0);
131}
132