|
Packit |
5c3484 |
/* Exercise mpz_fac_ui and mpz_bin_uiui.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
Copyright 2000-2002, 2012, 2013 Free Software Foundation, Inc.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
This file is part of the GNU MP Library test suite.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library test suite is free software; you can redistribute it
|
|
Packit |
5c3484 |
and/or modify it under the terms of the GNU General Public License as
|
|
Packit |
5c3484 |
published by the Free Software Foundation; either version 3 of the License,
|
|
Packit |
5c3484 |
or (at your option) any later version.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library test suite is distributed in the hope that it will be
|
|
Packit |
5c3484 |
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5c3484 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
Packit |
5c3484 |
Public License for more details.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
You should have received a copy of the GNU General Public License along with
|
|
Packit |
5c3484 |
the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include <stdio.h>
|
|
Packit |
5c3484 |
#include <stdlib.h>
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include "testutils.h"
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* Usage: t-fac_ui [x|num]
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
With no arguments testing goes up to the initial value of "limit" below.
|
|
Packit |
5c3484 |
With a number argument tests are carried that far, or with a literal "x"
|
|
Packit |
5c3484 |
tests are continued without limit (this being meant only for development
|
|
Packit |
5c3484 |
purposes). */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
void
|
|
Packit |
5c3484 |
try_mpz_bin_uiui (mpz_srcptr want, unsigned long n, unsigned long k)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_t got;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_init (got);
|
|
Packit |
5c3484 |
mpz_bin_uiui (got, n, k);
|
|
Packit |
5c3484 |
if (mpz_cmp (got, want) != 0)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
printf ("mpz_bin_uiui wrong\n");
|
|
Packit |
5c3484 |
printf (" n=%lu\n", n);
|
|
Packit |
5c3484 |
printf (" k=%lu\n", k);
|
|
Packit |
5c3484 |
printf (" got="); mpz_out_str (stdout, 10, got); printf ("\n");
|
|
Packit |
5c3484 |
printf (" want="); mpz_out_str (stdout, 10, want); printf ("\n");
|
|
Packit |
5c3484 |
abort();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
mpz_clear (got);
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* Test all bin(n,k) cases, with 0 <= k <= n + 1 <= count. */
|
|
Packit |
5c3484 |
void
|
|
Packit |
5c3484 |
bin_smallexaustive (unsigned int count)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_t want;
|
|
Packit |
5c3484 |
unsigned long n, k;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_init (want);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
for (n = 0; n < count; n++)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_set_ui (want, 1);
|
|
Packit |
5c3484 |
for (k = 0; k <= n; k++)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
try_mpz_bin_uiui (want, n, k);
|
|
Packit |
5c3484 |
mpz_mul_ui (want, want, n - k);
|
|
Packit |
5c3484 |
mpz_fdiv_q_ui (want, want, k + 1);
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
try_mpz_bin_uiui (want, n, k);
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_clear (want);
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* Test all fac(n) cases, with 0 <= n <= limit. */
|
|
Packit |
5c3484 |
void
|
|
Packit |
5c3484 |
fac_smallexaustive (unsigned int limit)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_t f, r;
|
|
Packit |
5c3484 |
unsigned long n;
|
|
Packit |
5c3484 |
mpz_init_set_si (f, 1); /* 0! = 1 */
|
|
Packit |
5c3484 |
mpz_init (r);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
for (n = 0; n < limit; n++)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_fac_ui (r, n);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (mpz_cmp (f, r) != 0)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
printf ("mpz_fac_ui(%lu) wrong\n", n);
|
|
Packit |
5c3484 |
printf (" got "); mpz_out_str (stdout, 10, r); printf("\n");
|
|
Packit |
5c3484 |
printf (" want "); mpz_out_str (stdout, 10, f); printf("\n");
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_mul_ui (f, f, n+1); /* (n+1)! = n! * (n+1) */
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_clear (f);
|
|
Packit |
5c3484 |
mpz_clear (r);
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
void checkWilson (mpz_t f, unsigned long n)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
unsigned long m;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_fac_ui (f, n - 1);
|
|
Packit |
5c3484 |
m = mpz_fdiv_ui (f, n);
|
|
Packit |
5c3484 |
if ( m != n - 1)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
printf ("mpz_fac_ui(%lu) wrong\n", n - 1);
|
|
Packit |
5c3484 |
printf (" Wilson's theorem not verified: got %lu, expected %lu.\n",m ,n - 1);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
void
|
|
Packit |
5c3484 |
checkprimes (unsigned long p1, unsigned long p2, unsigned long p3)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_t b, f;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (p1 - 1 != p2 - 1 + p3 - 1)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
printf ("checkprimes(%lu, %lu, %lu) wrong\n", p1, p2, p3);
|
|
Packit |
5c3484 |
printf (" %lu - 1 != %lu - 1 + %lu - 1 \n", p1, p2, p3);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_init (b);
|
|
Packit |
5c3484 |
mpz_init (f);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
checkWilson (b, p1); /* b = (p1-1)! */
|
|
Packit |
5c3484 |
checkWilson (f, p2); /* f = (p2-1)! */
|
|
Packit |
5c3484 |
mpz_divexact (b, b, f);
|
|
Packit |
5c3484 |
checkWilson (f, p3); /* f = (p3-1)! */
|
|
Packit |
5c3484 |
mpz_divexact (b, b, f); /* b = (p1-1)!/((p2-1)!(p3-1)!) */
|
|
Packit |
5c3484 |
mpz_bin_uiui (f, p1 - 1, p2 - 1);
|
|
Packit |
5c3484 |
if (mpz_cmp (f, b) != 0)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
printf ("checkprimes(%lu, %lu, %lu) wrong\n", p1, p2, p3);
|
|
Packit |
5c3484 |
printf (" got "); mpz_out_str (stdout, 10, b); printf("\n");
|
|
Packit |
5c3484 |
printf (" want "); mpz_out_str (stdout, 10, f); printf("\n");
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_clear (b);
|
|
Packit |
5c3484 |
mpz_clear (f);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
void
|
|
Packit |
5c3484 |
testmain (int argc, char *argv[])
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
unsigned long limit = 128;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (argc > 1 && argv[1][0] == 'x')
|
|
Packit |
5c3484 |
limit = ~ limit;
|
|
Packit |
5c3484 |
else if (argc > 1)
|
|
Packit |
5c3484 |
limit = atoi (argv[1]);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
checkprimes(1009, 733, 277);
|
|
Packit |
5c3484 |
fac_smallexaustive (limit);
|
|
Packit |
5c3484 |
bin_smallexaustive (limit);
|
|
Packit |
5c3484 |
}
|