1/* Test mpz_lcm and mpz_lcm_ui.
2
3Copyright 2001 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
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include "gmp.h"
26#include "gmp-impl.h"
27#include "tests.h"
28
29
30void
31check_all (mpz_ptr want, mpz_srcptr x_orig, mpz_srcptr y_orig)
32{
33  mpz_t  got, x, y;
34  int    negx, negy, swap, inplace;
35
36  mpz_init (got);
37  mpz_init_set (x, x_orig);
38  mpz_init_set (y, y_orig);
39
40  for (swap = 0; swap < 2; swap++)
41    {
42      mpz_swap (x, y);
43
44      for (negx = 0; negx < 2; negx++)
45	{
46	  mpz_neg (x, x);
47
48	  for (negy = 0; negy < 2; negy++)
49	    {
50	      mpz_neg (y, y);
51
52	      for (inplace = 0; inplace <= 1; inplace++)
53		{
54		  if (inplace)
55		    { mpz_set (got, x); mpz_lcm (got, got, y); }
56		  else
57		    mpz_lcm (got, x, y);
58		  MPZ_CHECK_FORMAT (got);
59
60		  if (mpz_cmp (got, want) != 0)
61		    {
62		      printf ("mpz_lcm wrong, inplace=%d\n", inplace);
63		    fail:
64		      mpz_trace ("x", x);
65		      mpz_trace ("y", y);
66		      mpz_trace ("got", got);
67		      mpz_trace ("want", want);
68		      abort ();
69		    }
70
71		  if (mpz_fits_ulong_p (y))
72		    {
73		      unsigned long  yu = mpz_get_ui (y);
74		      if (inplace)
75			{ mpz_set (got, x); mpz_lcm_ui (got, got, yu); }
76		      else
77			mpz_lcm_ui (got, x, yu);
78
79		      if (mpz_cmp (got, want) != 0)
80			{
81			  printf ("mpz_lcm_ui wrong, inplace=%d\n", inplace);
82			  printf    ("yu=%lu\n", yu);
83			  goto fail;
84			}
85		    }
86		}
87	    }
88	}
89    }
90
91  mpz_clear (got);
92  mpz_clear (x);
93  mpz_clear (y);
94}
95
96
97void
98check_primes (void)
99{
100  static unsigned long  prime[] = {
101    2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,
102    101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,
103    191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,
104    281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,
105    389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,
106  };
107  mpz_t  want, x, y;
108  int    i;
109
110  mpz_init (want);
111  mpz_init (x);
112  mpz_init (y);
113
114  /* New prime each time. */
115  mpz_set_ui (want, 1L);
116  for (i = 0; i < numberof (prime); i++)
117    {
118      mpz_set (x, want);
119      mpz_set_ui (y, prime[i]);
120      mpz_mul_ui (want, want, prime[i]);
121      check_all (want, x, y);
122    }
123
124  /* Old prime each time. */
125  mpz_set (x, want);
126  for (i = 0; i < numberof (prime); i++)
127    {
128      mpz_set_ui (y, prime[i]);
129      check_all (want, x, y);
130    }
131
132  /* One old, one new each time. */
133  mpz_set_ui (want, prime[0]);
134  for (i = 1; i < numberof (prime); i++)
135    {
136      mpz_set (x, want);
137      mpz_set_ui (y, prime[i] * prime[i-1]);
138      mpz_mul_ui (want, want, prime[i]);
139      check_all (want, x, y);
140    }
141
142  /* Triplets with A,B in x and B,C in y. */
143  mpz_set_ui (want, 1L);
144  mpz_set_ui (x, 1L);
145  mpz_set_ui (y, 1L);
146  for (i = 0; i+2 < numberof (prime); i += 3)
147    {
148      mpz_mul_ui (want, want, prime[i]);
149      mpz_mul_ui (want, want, prime[i+1]);
150      mpz_mul_ui (want, want, prime[i+2]);
151
152      mpz_mul_ui (x, x, prime[i]);
153      mpz_mul_ui (x, x, prime[i+1]);
154
155      mpz_mul_ui (y, y, prime[i+1]);
156      mpz_mul_ui (y, y, prime[i+2]);
157
158      check_all (want, x, y);
159    }
160
161
162  mpz_clear (want);
163  mpz_clear (x);
164  mpz_clear (y);
165}
166
167
168
169int
170main (int argc, char *argv[])
171{
172  tests_start ();
173
174  check_primes ();
175
176  tests_end ();
177  exit (0);
178}
179