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