source: trunk/third/gmp/tests/mpz/t-gcd.c @ 22254

Revision 22254, 4.8 KB checked in by ghudson, 19 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r22253, which included commits to RCS files with non-trunk default branches.
Line 
1/* Test mpz_gcd, mpz_gcdext, mpz_mul, mpz_tdiv_r, mpz_add, mpz_cmp,
2   mpz_cmp_ui, mpz_init_set, mpz_set, mpz_clear.
3
4Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2002, 2004 Free Software
5Foundation, Inc.
6
7This file is part of the GNU MP Library.
8
9The GNU MP Library is free software; you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation; either version 2.1 of the License, or (at your
12option) any later version.
13
14The GNU MP Library is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
21the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22MA 02111-1307, USA. */
23
24#include <stdio.h>
25#include <stdlib.h>
26
27#include "gmp.h"
28#include "gmp-impl.h"
29#include "tests.h"
30
31void dump_abort _PROTO ((int, mpz_t, mpz_t));
32void debug_mp _PROTO ((mpz_t, int));
33
34void
35check_data (void)
36{
37  static const struct {
38    const char *a;
39    const char *b;
40    const char *want;
41  } data[] = {
42    /* This tickled a bug in gmp 4.1.2 mpn/x86/k6/gcd_finda.asm. */
43    { "0x3FFC000007FFFFFFFFFF00000000003F83FFFFFFFFFFFFFFF80000000000000001",
44      "0x1FFE0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC000000000000000000000001",
45      "5" }
46  };
47
48  mpz_t  a, b, got, want;
49  int    i;
50
51  mpz_init (a);
52  mpz_init (b);
53  mpz_init (got);
54  mpz_init (want);
55
56  for (i = 0; i < numberof (data); i++)
57    {
58      mpz_set_str_or_abort (a, data[i].a, 0);
59      mpz_set_str_or_abort (b, data[i].b, 0);
60      mpz_set_str_or_abort (want, data[i].want, 0);
61      mpz_gcd (got, a, b);
62      MPZ_CHECK_FORMAT (got);
63      if (mpz_cmp (got, want) != 0)
64        {
65          printf    ("mpz_gcd wrong on data[%d]\n", i);
66          printf    (" a  %s\n", data[i].a);
67          printf    (" b  %s\n", data[i].b);
68          mpz_trace (" a", a);
69          mpz_trace (" b", b);
70          mpz_trace (" want", want);
71          mpz_trace (" got ", got);
72          abort ();
73        }
74    }
75
76  mpz_clear (a);
77  mpz_clear (b);
78  mpz_clear (got);
79  mpz_clear (want);
80}
81
82int
83main (int argc, char **argv)
84{
85  mpz_t op1, op2, x;
86  mpz_t gcd, gcd2, s, t;
87  mpz_t temp1, temp2;
88  mp_size_t op1_size, op2_size, x_size;
89  int i;
90  int reps = 2000;
91  gmp_randstate_ptr rands;
92  mpz_t bs;
93  unsigned long bsi, size_range;
94
95  tests_start ();
96  rands = RANDS;
97
98  check_data ();
99
100  mpz_init (bs);
101
102  if (argc == 2)
103    reps = atoi (argv[1]);
104
105  mpz_init (op1);
106  mpz_init (op2);
107  mpz_init (x);
108  mpz_init (gcd);
109  mpz_init (gcd2);
110  mpz_init (temp1);
111  mpz_init (temp2);
112  mpz_init (s);
113  mpz_init (t);
114
115  for (i = 0; i < reps; i++)
116    {
117      mpz_urandomb (bs, rands, 32);
118      size_range = mpz_get_ui (bs) % 12 + 2; /* 0..8191 bit operands */
119
120      mpz_urandomb (bs, rands, size_range);
121      op1_size = mpz_get_ui (bs);
122      mpz_rrandomb (op1, rands, op1_size);
123
124      mpz_urandomb (bs, rands, size_range);
125      op2_size = mpz_get_ui (bs);
126      mpz_rrandomb (op2, rands, op2_size);
127
128      mpz_urandomb (bs, rands, size_range);
129      x_size = mpz_get_ui (bs);
130      mpz_rrandomb (x, rands, x_size);
131
132      mpz_urandomb (bs, rands, 2);
133      bsi = mpz_get_ui (bs);
134      if ((bsi & 1) != 0)
135        mpz_neg (op1, op1);
136      if ((bsi & 2) != 0)
137        mpz_neg (op2, op2);
138
139      /* printf ("%ld %ld\n", SIZ (op1), SIZ (op2)); */
140
141      mpz_mul (op1, op1, x);
142      mpz_mul (op2, op2, x);
143
144      mpz_gcd (gcd, op1, op2);
145      /* We know GCD will be at least X, since we multiplied both operands
146         with it.  */
147      if (mpz_cmp (gcd, x) < 0 && mpz_sgn (op1) != 0 && mpz_sgn (op2) != 0)
148        dump_abort (i, op1, op2);
149
150      if (mpz_fits_ulong_p (op2))
151        {
152          mpz_gcd_ui (gcd2, op1, mpz_get_ui (op2));
153          if (mpz_cmp (gcd, gcd2))
154            dump_abort (i, op1, op2);
155        }
156
157      mpz_gcdext (gcd2, s, t, op1, op2);
158      if (mpz_cmp (gcd, gcd2))
159        dump_abort (i, op1, op2);
160
161      mpz_gcdext (gcd2, s, NULL, op1, op2);
162      if (mpz_cmp (gcd, gcd2))
163        dump_abort (i, op1, op2);
164
165      mpz_mul (temp1, s, op1);
166      mpz_mul (temp2, t, op2);
167      mpz_add (gcd2, temp1, temp2);
168      if (mpz_cmp (gcd, gcd2))
169        dump_abort (i, op1, op2);
170    }
171
172  mpz_clear (bs);
173  mpz_clear (op1);
174  mpz_clear (op2);
175  mpz_clear (x);
176  mpz_clear (gcd);
177  mpz_clear (gcd2);
178  mpz_clear (temp1);
179  mpz_clear (temp2);
180  mpz_clear (s);
181  mpz_clear (t);
182
183  tests_end ();
184  exit (0);
185}
186
187void
188dump_abort (int testnr, mpz_t op1, mpz_t op2)
189{
190  fprintf (stderr, "ERROR in test %d\n", testnr);
191  fprintf (stderr, "op1 = "); debug_mp (op1, -16);
192  fprintf (stderr, "op2 = "); debug_mp (op2, -16);
193  abort();
194}
195
196void
197debug_mp (mpz_t x, int base)
198{
199  mpz_out_str (stderr, base, x); fputc ('\n', stderr);
200}
Note: See TracBrowser for help on using the repository browser.