xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-lcm.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
1 /* Test mpz_lcm and mpz_lcm_ui.
2 
3 Copyright 2001 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library test suite.
6 
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11 
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
19 
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "gmp-impl.h"
26 #include "tests.h"
27 
28 
29 void
check_all(mpz_ptr want,mpz_srcptr x_orig,mpz_srcptr y_orig)30 check_all (mpz_ptr want, mpz_srcptr x_orig, mpz_srcptr y_orig)
31 {
32   mpz_t  got, x, y;
33   int    negx, negy, swap, inplace;
34 
35   mpz_init (got);
36   mpz_init_set (x, x_orig);
37   mpz_init_set (y, y_orig);
38 
39   for (swap = 0; swap < 2; swap++)
40     {
41       mpz_swap (x, y);
42 
43       for (negx = 0; negx < 2; negx++)
44 	{
45 	  mpz_neg (x, x);
46 
47 	  for (negy = 0; negy < 2; negy++)
48 	    {
49 	      mpz_neg (y, y);
50 
51 	      for (inplace = 0; inplace <= 1; inplace++)
52 		{
53 		  if (inplace)
54 		    { mpz_set (got, x); mpz_lcm (got, got, y); }
55 		  else
56 		    mpz_lcm (got, x, y);
57 		  MPZ_CHECK_FORMAT (got);
58 
59 		  if (mpz_cmp (got, want) != 0)
60 		    {
61 		      printf ("mpz_lcm wrong, inplace=%d\n", inplace);
62 		    fail:
63 		      mpz_trace ("x", x);
64 		      mpz_trace ("y", y);
65 		      mpz_trace ("got", got);
66 		      mpz_trace ("want", want);
67 		      abort ();
68 		    }
69 
70 		  if (mpz_fits_ulong_p (y))
71 		    {
72 		      unsigned long  yu = mpz_get_ui (y);
73 		      if (inplace)
74 			{ mpz_set (got, x); mpz_lcm_ui (got, got, yu); }
75 		      else
76 			mpz_lcm_ui (got, x, yu);
77 
78 		      if (mpz_cmp (got, want) != 0)
79 			{
80 			  printf ("mpz_lcm_ui wrong, inplace=%d\n", inplace);
81 			  printf    ("yu=%lu\n", yu);
82 			  goto fail;
83 			}
84 		    }
85 		}
86 	    }
87 	}
88     }
89 
90   mpz_clear (got);
91   mpz_clear (x);
92   mpz_clear (y);
93 }
94 
95 
96 void
check_primes(void)97 check_primes (void)
98 {
99   static unsigned long  prime[] = {
100     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,
101     101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,
102     191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,
103     281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,
104     389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,
105   };
106   mpz_t  want, x, y;
107   int    i;
108 
109   mpz_init (want);
110   mpz_init (x);
111   mpz_init (y);
112 
113   /* Check zeros. */
114   mpz_set_ui (want, 0);
115   mpz_set_ui (x, 1);
116   check_all (want, want, want);
117   check_all (want, want, x);
118   check_all (want, x, want);
119 
120   /* New prime each time. */
121   mpz_set_ui (want, 1L);
122   for (i = 0; i < numberof (prime); i++)
123     {
124       mpz_set (x, want);
125       mpz_set_ui (y, prime[i]);
126       mpz_mul_ui (want, want, prime[i]);
127       check_all (want, x, y);
128     }
129 
130   /* Old prime each time. */
131   mpz_set (x, want);
132   for (i = 0; i < numberof (prime); i++)
133     {
134       mpz_set_ui (y, prime[i]);
135       check_all (want, x, y);
136     }
137 
138   /* One old, one new each time. */
139   mpz_set_ui (want, prime[0]);
140   for (i = 1; i < numberof (prime); i++)
141     {
142       mpz_set (x, want);
143       mpz_set_ui (y, prime[i] * prime[i-1]);
144       mpz_mul_ui (want, want, prime[i]);
145       check_all (want, x, y);
146     }
147 
148   /* Triplets with A,B in x and B,C in y. */
149   mpz_set_ui (want, 1L);
150   mpz_set_ui (x, 1L);
151   mpz_set_ui (y, 1L);
152   for (i = 0; i+2 < numberof (prime); i += 3)
153     {
154       mpz_mul_ui (want, want, prime[i]);
155       mpz_mul_ui (want, want, prime[i+1]);
156       mpz_mul_ui (want, want, prime[i+2]);
157 
158       mpz_mul_ui (x, x, prime[i]);
159       mpz_mul_ui (x, x, prime[i+1]);
160 
161       mpz_mul_ui (y, y, prime[i+1]);
162       mpz_mul_ui (y, y, prime[i+2]);
163 
164       check_all (want, x, y);
165     }
166 
167 
168   mpz_clear (want);
169   mpz_clear (x);
170   mpz_clear (y);
171 }
172 
173 
174 
175 int
main(int argc,char * argv[])176 main (int argc, char *argv[])
177 {
178   tests_start ();
179 
180   check_primes ();
181 
182   tests_end ();
183   exit (0);
184 }
185