1/* 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} 96