blob: 1f46c435c0c8eff6ede6609e6cff036d43086b63 [file] [log] [blame]
Austin Schuhbb1338c2024-06-15 19:31:16 -07001/*
2
3Copyright 2012, 2013 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
19
20#include <limits.h>
21#include <stdlib.h>
22#include <stdio.h>
23
24#include "testutils.h"
25
26#define MAXBITS 400
27#define COUNT 10000
28
29/* Called when s is supposed to be floor(root(u,z)), and r = u - s^z */
30static int
31rootrem_valid_p (const mpz_t u, const mpz_t s, const mpz_t r, unsigned long z)
32{
33 mpz_t t;
34
35 mpz_init (t);
36 if (mpz_fits_ulong_p (s))
37 mpz_ui_pow_ui (t, mpz_get_ui (s), z);
38 else
39 mpz_pow_ui (t, s, z);
40 mpz_sub (t, u, t);
41 if ((mpz_sgn (t) != mpz_sgn(u) && mpz_sgn (t) != 0) || mpz_cmp (t, r) != 0)
42 {
43 mpz_clear (t);
44 return 0;
45 }
46 if (mpz_sgn (s) > 0)
47 mpz_add_ui (t, s, 1);
48 else
49 mpz_sub_ui (t, s, 1);
50 mpz_pow_ui (t, t, z);
51 if (mpz_cmpabs (t, u) <= 0)
52 {
53 mpz_clear (t);
54 return 0;
55 }
56
57 mpz_clear (t);
58 return 1;
59}
60
61void
62testmain (int argc, char **argv)
63{
64 unsigned i;
65 unsigned long e;
66 mpz_t u, s, r, bs;
67
68 mpz_init (u);
69 mpz_init (s);
70 mpz_init (r);
71 mpz_init (bs);
72
73 for (i = 0; i < COUNT; i++)
74 {
75 mini_rrandomb (u, MAXBITS);
76 mini_rrandomb (bs, 12);
77 e = mpz_getlimbn (bs, 0) % mpz_sizeinbase (u, 2) + 1;
78 if ((e & 1) && (mpz_getlimbn (bs, 0) & (1L<<10)))
79 mpz_neg (u, u);
80 mpz_rootrem (s, r, u, e);
81
82 if (!rootrem_valid_p (u, s, r, e))
83 {
84 fprintf (stderr, "mpz_rootrem(%lu-th) failed:\n", e);
85 dump ("u", u);
86 dump ("root", s);
87 dump ("rem", r);
88 abort ();
89 }
90 }
91 mpz_clear (bs);
92 mpz_clear (u);
93 mpz_clear (s);
94 mpz_clear (r);
95}