1 /*
2     Copyright (C) 2009 William Hart
3 
4     This file is part of FLINT.
5 
6     FLINT is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
10 */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <gmp.h>
15 #include "flint.h"
16 #include "ulong_extras.h"
17 
main(void)18 int main(void)
19 {
20    int i, result;
21    const mp_limb_t * primes;
22    const double * inverses;
23 
24    FLINT_TEST_INIT(state);
25 
26    flint_printf("remove2_precomp....");
27    fflush(stdout);
28 
29    primes = n_primes_arr_readonly(10000);
30    inverses = n_prime_inverses_arr_readonly(10000);
31 
32    for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test random numbers */
33    {
34       mp_limb_t n1, n2, orig_n;
35       mpz_t d_n2, d_n1, d_p;
36       int exp1, exp2;
37       ulong j;
38 
39       mpz_init(d_n1);
40       mpz_init(d_n2);
41       mpz_init(d_p);
42 
43       n1 = n_randtest_not_zero(state);
44       orig_n = n1;
45 
46       for (j = 0; j < FLINT_NUM_PRIMES_SMALL/10; j++)
47       {
48          flint_mpz_set_ui(d_n1, n1);
49          flint_mpz_set_ui(d_p, flint_primes_small[j]);
50          exp1 = n_remove2_precomp(&n1, primes[j], inverses[j]);
51          exp2 = mpz_remove(d_n2, d_n1, d_p);
52          n2 = flint_mpz_get_ui(d_n2);
53 
54          result = ((exp1 == exp2) && (n1 == n2));
55          if (!result)
56          {
57             flint_printf("FAIL\n");
58             flint_printf("n = %wu, exp1 = %d, exp2 = %d, n1 = %wu, n2 = %wu, p = %d\n", orig_n, exp1, exp2, n1, n2, flint_primes_small[j]);
59             abort();
60          }
61       }
62 
63       mpz_clear(d_n1);
64       mpz_clear(d_n2);
65       mpz_clear(d_p);
66    }
67 
68    for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test perfect powers */
69    {
70       mp_limb_t n1, n2, orig_n, base;
71       mpz_t d_n2, d_n1, d_p;
72       int exp1, exp2, exp;
73       ulong j;
74 
75       mpz_init(d_n1);
76       mpz_init(d_n2);
77       mpz_init(d_p);
78 
79       base = n_randtest_not_zero(state);
80       n1 = base;
81       exp = n_randint(state, FLINT_BITS/FLINT_BIT_COUNT(n1)) + 1;
82       n1 = n_pow(base, exp);
83 
84       orig_n = n1;
85 
86       for (j = 0; j < FLINT_NUM_PRIMES_SMALL/10; j++)
87       {
88          flint_mpz_set_ui(d_n1, n1);
89          flint_mpz_set_ui(d_p, flint_primes_small[j]);
90          exp1 = n_remove2_precomp(&n1, primes[j], inverses[j]);
91          exp2 = mpz_remove(d_n2, d_n1, d_p);
92          n2 = flint_mpz_get_ui(d_n2);
93 
94          result = ((exp1 == exp2) && (n1 == n2));
95          if (!result)
96          {
97             flint_printf("FAIL:\n");
98             flint_printf("n = %wu, exp1 = %d, exp2 = %d, n1 = %wu, n2 = %wu, p = %d\n", orig_n, exp1, exp2, n1, n2, flint_primes_small[j]);
99             abort();
100          }
101       }
102 
103       mpz_clear(d_n1);
104       mpz_clear(d_n2);
105       mpz_clear(d_p);
106    }
107 
108    FLINT_TEST_CLEANUP(state);
109 
110    flint_printf("PASS\n");
111    return 0;
112 }
113