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