Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
# Note: Requires GNU make
# Copyright 2011, 2012, 2014, 2016, 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/.
srcdir=.
MINI_GMP_DIR=..
CC = gcc
CFLAGS = -O -Wall -g
CPPFLAGS =
LDFLAGS =
LIBS = -lgmp -lm -lmcheck
CHECK_PROGRAMS = t-add t-sub t-mul t-invert t-div t-div_2exp \
t-double t-cmp_d t-gcd t-lcm t-import t-comb t-signed \
t-sqrt t-root t-powm t-logops t-bitops t-scan t-str \
t-reuse t-aorsmul t-limbs t-cong t-pprime_p t-lucm \
t-mpq_addsub t-mpq_muldiv t-mpq_muldiv_2exp t-mpq_str \
t-mpq_double
# Default TESTS to all tests, allowing overriding TESTS for building tests
# without running them.
TESTS = $(CHECK_PROGRAMS)
MISC_OBJS = hex-random.o mini-random.o testutils.o
all:
clean:
rm -f *.o $(CHECK_PROGRAMS)
%: %.c
.c:
# Keep object files
.PRECIOUS: %.o
%.o: %.c $(MINI_GMP_DIR)/mini-gmp.h $(MINI_GMP_DIR)/mini-mpq.h hex-random.h mini-random.h
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
testutils.o: $(MINI_GMP_DIR)/mini-gmp.c $(MINI_GMP_DIR)/mini-mpq.c
%: %.o $(MISC_OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
# Missing tests include:
# mpz_cmp_d, mpz_popcount, mpz_hamdist, mpz_ui_pow_ui
check: $(CHECK_PROGRAMS)
$(srcdir)/run-tests $(TESTS)

View File

@@ -0,0 +1,573 @@
/*
Copyright 2011, 2016, 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 <time.h>
#ifdef __unix__
# include <unistd.h>
# include <sys/time.h>
#endif
#include "gmp.h"
#include "hex-random.h"
/* FIXME: gmp-impl.h included only for mpz_lucas_mod */
/* #include "gmp-impl.h" */
#if defined (__cplusplus)
extern "C" {
#endif
#define mpz_lucas_mod __gmpz_lucas_mod
__GMP_DECLSPEC int mpz_lucas_mod (mpz_ptr, mpz_ptr, long, mp_bitcnt_t, mpz_srcptr, mpz_ptr, mpz_ptr);
#if defined (__cplusplus)
}
#endif
static gmp_randstate_t state;
static void
mkseed (mpz_t seed)
{
FILE *f = fopen ("/dev/urandom", "rb");
if (f)
{
unsigned char buf[6];
size_t res;
setbuf (f, NULL);
res = fread (buf, sizeof(buf), 1, f);
fclose (f);
if (res == 1)
{
mpz_import (seed, sizeof(buf), 1, 1, 0, 0, buf);
return;
}
}
#ifdef __unix__
{
struct timeval tv;
mpz_t usec;
mpz_init (usec);
gettimeofday (&tv, NULL);
mpz_set_ui (seed, tv.tv_sec);
mpz_set_ui (usec, tv.tv_usec);
/* usec fits in 20 bits, shift left to make it 48 bits. */
mpz_mul_2exp (usec, usec, 28);
mpz_xor (seed, seed, usec);
mpz_clear (usec);
}
#else
mpz_set_ui (seed, time (NULL));
#endif
}
void
hex_random_init (void)
{
mpz_t seed;
char *env_seed;
mpz_init (seed);
env_seed = getenv ("GMP_CHECK_RANDOMIZE");
if (env_seed && env_seed[0])
{
mpz_set_str (seed, env_seed, 0);
if (mpz_cmp_ui (seed, 0) != 0)
gmp_printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%Zd\n", seed);
else
{
mkseed (seed);
gmp_printf ("Seed GMP_CHECK_RANDOMIZE=%Zd (include this in bug reports)\n", seed);
}
fflush (stdout);
}
else
mpz_set_ui (seed, 4711);
gmp_randinit_default (state);
gmp_randseed (state, seed);
mpz_clear (seed);
}
char *
hex_urandomb (unsigned long bits)
{
char *res;
mpz_t x;
mpz_init (x);
mpz_urandomb (x, state, bits);
gmp_asprintf (&res, "%Zx", x);
mpz_clear (x);
return res;
}
char *
hex_rrandomb (unsigned long bits)
{
char *res;
mpz_t x;
mpz_init (x);
mpz_rrandomb (x, state, bits);
gmp_asprintf (&res, "%Zx", x);
mpz_clear (x);
return res;
}
char *
hex_rrandomb_export (void *dst, size_t *countp,
int order, size_t size, int endian, unsigned long bits)
{
char *res;
mpz_t x;
mpz_init (x);
mpz_rrandomb (x, state, bits);
gmp_asprintf (&res, "%Zx", x);
mpz_export (dst, countp, order, size, endian, 0, x);
mpz_clear (x);
return res;
}
void hex_random_op2 (enum hex_random_op op, unsigned long maxbits,
char **ap, char **rp)
{
mpz_t a, r;
unsigned long abits;
unsigned signs;
mpz_init (a);
mpz_init (r);
abits = gmp_urandomb_ui (state, 32) % maxbits;
mpz_rrandomb (a, state, abits);
signs = gmp_urandomb_ui (state, 1);
if (signs & 1)
mpz_neg (a, a);
switch (op)
{
default:
abort ();
case OP_SQR:
mpz_mul (r, a, a);
break;
}
gmp_asprintf (ap, "%Zx", a);
gmp_asprintf (rp, "%Zx", r);
mpz_clear (a);
mpz_clear (r);
}
void
hex_random_op3 (enum hex_random_op op, unsigned long maxbits,
char **ap, char **bp, char **rp)
{
mpz_t a, b, r;
unsigned long abits, bbits;
unsigned signs;
mpz_init (a);
mpz_init (b);
mpz_init (r);
abits = gmp_urandomb_ui (state, 32) % maxbits;
bbits = gmp_urandomb_ui (state, 32) % maxbits;
mpz_rrandomb (a, state, abits);
mpz_rrandomb (b, state, bbits);
signs = gmp_urandomb_ui (state, 3);
if (signs & 1)
mpz_neg (a, a);
if (signs & 2)
mpz_neg (b, b);
switch (op)
{
default:
abort ();
case OP_ADD:
mpz_add (r, a, b);
break;
case OP_SUB:
mpz_sub (r, a, b);
break;
case OP_MUL:
mpz_mul (r, a, b);
break;
case OP_GCD:
if (signs & 4)
{
/* Produce a large gcd */
unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits;
mpz_rrandomb (r, state, gbits);
mpz_mul (a, a, r);
mpz_mul (b, b, r);
}
mpz_gcd (r, a, b);
break;
case OP_LCM:
if (signs & 4)
{
/* Produce a large gcd */
unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits;
mpz_rrandomb (r, state, gbits);
mpz_mul (a, a, r);
mpz_mul (b, b, r);
}
mpz_lcm (r, a, b);
break;
case OP_AND:
mpz_and (r, a, b);
break;
case OP_IOR:
mpz_ior (r, a, b);
break;
case OP_XOR:
mpz_xor (r, a, b);
break;
}
gmp_asprintf (ap, "%Zx", a);
gmp_asprintf (bp, "%Zx", b);
gmp_asprintf (rp, "%Zx", r);
mpz_clear (a);
mpz_clear (b);
mpz_clear (r);
}
void
hex_random_op4 (enum hex_random_op op, unsigned long maxbits,
char **ap, char **bp, char **cp, char **dp)
{
mpz_t a, b, c, d;
unsigned long abits, bbits;
unsigned signs;
mpz_init (a);
mpz_init (b);
mpz_init (c);
mpz_init (d);
if (op == OP_POWM)
{
unsigned long cbits;
abits = gmp_urandomb_ui (state, 32) % maxbits;
bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits;
cbits = 2 + gmp_urandomb_ui (state, 32) % maxbits;
mpz_rrandomb (a, state, abits);
mpz_rrandomb (b, state, bbits);
mpz_rrandomb (c, state, cbits);
signs = gmp_urandomb_ui (state, 3);
if (signs & 1)
mpz_neg (a, a);
if (signs & 2)
{
mpz_t g;
/* If we negate the exponent, must make sure that gcd(a, c) = 1 */
if (mpz_sgn (a) == 0)
mpz_set_ui (a, 1);
else
{
mpz_init (g);
for (;;)
{
mpz_gcd (g, a, c);
if (mpz_cmp_ui (g, 1) == 0)
break;
mpz_divexact (a, a, g);
}
mpz_clear (g);
}
mpz_neg (b, b);
}
if (signs & 4)
mpz_neg (c, c);
mpz_powm (d, a, b, c);
}
else
{
unsigned long qbits;
bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits;
qbits = gmp_urandomb_ui (state, 32) % maxbits;
abits = bbits + qbits;
if (abits > 30)
abits -= 30;
else
abits = 0;
mpz_rrandomb (a, state, abits);
mpz_rrandomb (b, state, bbits);
signs = gmp_urandomb_ui (state, 2);
if (signs & 1)
mpz_neg (a, a);
if (signs & 2)
mpz_neg (b, b);
switch (op)
{
default:
abort ();
case OP_CDIV:
mpz_cdiv_qr (c, d, a, b);
break;
case OP_FDIV:
mpz_fdiv_qr (c, d, a, b);
break;
case OP_TDIV:
mpz_tdiv_qr (c, d, a, b);
break;
}
}
gmp_asprintf (ap, "%Zx", a);
gmp_asprintf (bp, "%Zx", b);
gmp_asprintf (cp, "%Zx", c);
gmp_asprintf (dp, "%Zx", d);
mpz_clear (a);
mpz_clear (b);
mpz_clear (c);
mpz_clear (d);
}
void
hex_random_bit_op (enum hex_random_op op, unsigned long maxbits,
char **ap, unsigned long *b, char **rp)
{
mpz_t a, r;
unsigned long abits, bbits;
unsigned signs;
mpz_init (a);
mpz_init (r);
abits = gmp_urandomb_ui (state, 32) % maxbits;
bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100);
mpz_rrandomb (a, state, abits);
signs = gmp_urandomb_ui (state, 1);
if (signs & 1)
mpz_neg (a, a);
switch (op)
{
default:
abort ();
case OP_SETBIT:
mpz_set (r, a);
mpz_setbit (r, bbits);
break;
case OP_CLRBIT:
mpz_set (r, a);
mpz_clrbit (r, bbits);
break;
case OP_COMBIT:
mpz_set (r, a);
mpz_combit (r, bbits);
break;
case OP_CDIV_Q_2:
mpz_cdiv_q_2exp (r, a, bbits);
break;
case OP_CDIV_R_2:
mpz_cdiv_r_2exp (r, a, bbits);
break;
case OP_FDIV_Q_2:
mpz_fdiv_q_2exp (r, a, bbits);
break;
case OP_FDIV_R_2:
mpz_fdiv_r_2exp (r, a, bbits);
break;
case OP_TDIV_Q_2:
mpz_tdiv_q_2exp (r, a, bbits);
break;
case OP_TDIV_R_2:
mpz_tdiv_r_2exp (r, a, bbits);
break;
}
gmp_asprintf (ap, "%Zx", a);
*b = bbits;
gmp_asprintf (rp, "%Zx", r);
mpz_clear (a);
mpz_clear (r);
}
void
hex_random_scan_op (enum hex_random_op op, unsigned long maxbits,
char **ap, unsigned long *b, unsigned long *r)
{
mpz_t a;
unsigned long abits, bbits;
unsigned signs;
mpz_init (a);
abits = gmp_urandomb_ui (state, 32) % maxbits;
bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100);
mpz_rrandomb (a, state, abits);
signs = gmp_urandomb_ui (state, 1);
if (signs & 1)
mpz_neg (a, a);
switch (op)
{
default:
abort ();
case OP_SCAN0:
*r = mpz_scan0 (a, bbits);
break;
case OP_SCAN1:
*r = mpz_scan1 (a, bbits);
break;
}
gmp_asprintf (ap, "%Zx", a);
*b = bbits;
mpz_clear (a);
}
void
hex_random_str_op (unsigned long maxbits,
int base, char **ap, char **rp)
{
mpz_t a;
unsigned long abits;
unsigned signs;
mpz_init (a);
abits = gmp_urandomb_ui (state, 32) % maxbits;
mpz_rrandomb (a, state, abits);
signs = gmp_urandomb_ui (state, 2);
if (signs & 1)
mpz_neg (a, a);
*ap = mpz_get_str (NULL, 16, a);
*rp = mpz_get_str (NULL, base, a);
mpz_clear (a);
}
void hex_random_lucm_op (unsigned long maxbits,
char **vp, char **qp, char **mp,
long *Q, unsigned long *b0, int *res)
{
mpz_t m, v, q, t1, t2;
unsigned long mbits;
mpz_init (m);
mpz_init (v);
mpz_init (q);
mpz_init (t1);
mpz_init (t2);
*Q = gmp_urandomb_ui (state, 14) + 1;
do
{
mbits = gmp_urandomb_ui (state, 32) % maxbits + 5;
mpz_rrandomb (m, state, mbits);
*b0 = gmp_urandomb_ui (state, 32) % (mbits - 3) + 2;
/* The GMP implementation uses the exponent (m >> b0) + 1. */
/* mini-gmp implementation uses the exponent (m >> b0) | 1. */
/* They are the same (and are used) only when (m >> b0) is even */
mpz_clrbit (m, *b0);
/* mini-gmp implementation only works if the modulus is odd. */
mpz_setbit (m, 0);
}
while (mpz_gcd_ui (NULL, m, *Q) != 1);
if (*Q == 1 || gmp_urandomb_ui (state, 1))
*Q = - *Q;
#if (__GNU_MP_VERSION == 6 && (__GNU_MP_VERSION_MINOR > 1 || __GNU_MP_VERSION_PATCHLEVEL > 9))
*res = mpz_lucas_mod (v, q, *Q, *b0, m, t1, t2);
#else
*b0 = 0;
#endif
gmp_asprintf (vp, "%Zx", v);
gmp_asprintf (qp, "%Zx", q);
gmp_asprintf (mp, "%Zx", m);
mpz_clear (m);
mpz_clear (v);
mpz_clear (q);
mpz_clear (t1);
mpz_clear (t2);
}
void
hex_mpq_random_str_op (unsigned long maxbits,
int base, char **ap, char **rp)
{
mpq_t a;
unsigned long abits;
unsigned signs;
mpq_init (a);
abits = gmp_urandomb_ui (state, 32) % maxbits;
mpz_rrandomb (mpq_numref (a), state, abits);
mpz_rrandomb (mpq_denref (a), state, abits);
mpz_add_ui (mpq_denref (a), mpq_denref (a), 1);
mpq_canonicalize (a);
signs = gmp_urandomb_ui (state, 2);
if (signs & 1)
mpq_neg (a, a);
*ap = mpq_get_str (NULL, 16, a);
*rp = mpq_get_str (NULL, base, a);
mpq_clear (a);
}

View File

@@ -0,0 +1,55 @@
/*
Copyright 2011, 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/. */
enum hex_random_op
{
OP_ADD, OP_SUB, OP_MUL, OP_SQR,
OP_CDIV, OP_FDIV, OP_TDIV,
OP_CDIV_Q_2, OP_CDIV_R_2,
OP_FDIV_Q_2, OP_FDIV_R_2,
OP_TDIV_Q_2, OP_TDIV_R_2,
OP_GCD, OP_LCM, OP_POWM, OP_AND, OP_IOR, OP_XOR,
OP_SETBIT, OP_CLRBIT, OP_COMBIT,
OP_SCAN0, OP_SCAN1,
};
void hex_random_init (void);
char *hex_urandomb (unsigned long bits);
char *hex_rrandomb (unsigned long bits);
char *hex_rrandomb_export (void *dst, size_t *countp,
int order, size_t size, int endian,
unsigned long bits);
void hex_random_op2 (enum hex_random_op op, unsigned long maxbits,
char **ap, char **rp);
void hex_random_op3 (enum hex_random_op op, unsigned long maxbits,
char **ap, char **bp, char **rp);
void hex_random_op4 (enum hex_random_op op, unsigned long maxbits,
char **ap, char **bp, char **rp, char **qp);
void hex_random_bit_op (enum hex_random_op op, unsigned long maxbits,
char **ap, unsigned long *b, char **rp);
void hex_random_scan_op (enum hex_random_op op, unsigned long maxbits,
char **ap, unsigned long *b, unsigned long *r);
void hex_random_str_op (unsigned long maxbits,
int base, char **ap, char **rp);
void hex_random_lucm_op (unsigned long maxbits,
char **vp, char **qp, char **mp,
long *Q, unsigned long *b0, int *res);
void hex_mpq_random_str_op (unsigned long maxbits,
int base, char **ap, char **rp);

View File

@@ -0,0 +1,160 @@
/*
Copyright 2011, 2013, 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 "mini-random.h"
static void
set_str (mpz_t r, const char *s)
{
if (mpz_set_str (r, s, 16) != 0)
{
fprintf (stderr, "mpz_set_str failed on input %s\n", s);
abort ();
}
}
void
mini_urandomb (mpz_t r, unsigned long bits)
{
char *s;
s = hex_urandomb (bits);
set_str (r, s);
free (s);
}
void
mini_rrandomb (mpz_t r, unsigned long bits)
{
char *s;
s = hex_rrandomb (bits);
set_str (r, s);
free (s);
}
void
mini_rrandomb_export (mpz_t r, void *dst, size_t *countp,
int order, size_t size, int endian, unsigned long bits)
{
char *s;
s = hex_rrandomb_export (dst, countp, order, size, endian, bits);
set_str (r, s);
free (s);
}
void
mini_random_op2 (enum hex_random_op op, unsigned long maxbits,
mpz_t a, mpz_t r)
{
char *ap;
char *rp;
hex_random_op2 (op, maxbits, &ap, &rp);
set_str (a, ap);
set_str (r, rp);
free (ap);
free (rp);
}
void
mini_random_op3 (enum hex_random_op op, unsigned long maxbits,
mpz_t a, mpz_t b, mpz_t r)
{
char *ap;
char *bp;
char *rp;
hex_random_op3 (op, maxbits, &ap, &bp, &rp);
set_str (a, ap);
set_str (b, bp);
set_str (r, rp);
free (ap);
free (bp);
free (rp);
}
void
mini_random_op4 (enum hex_random_op op, unsigned long maxbits,
mpz_t a, mpz_t b, mpz_t c, mpz_t d)
{
char *ap;
char *bp;
char *cp;
char *dp;
hex_random_op4 (op, maxbits, &ap, &bp, &cp, &dp);
set_str (a, ap);
set_str (b, bp);
set_str (c, cp);
set_str (d, dp);
free (ap);
free (bp);
free (cp);
free (dp);
}
void
mini_random_bit_op (enum hex_random_op op, unsigned long maxbits,
mpz_t a, mp_bitcnt_t *b, mpz_t r)
{
char *ap;
char *rp;
hex_random_bit_op (op, maxbits, &ap, b, &rp);
set_str (a, ap);
set_str (r, rp);
free (ap);
free (rp);
}
void
mini_random_scan_op (enum hex_random_op op, unsigned long maxbits,
mpz_t a, mp_bitcnt_t *b, mp_bitcnt_t *r)
{
char *ap;
hex_random_scan_op (op, maxbits, &ap, b, r);
set_str (a, ap);
free (ap);
}
void
mini_random_lucm_op (unsigned long maxbits, mpz_t v, mpz_t q, mpz_t m,
long *Q, unsigned long *b0, int *res)
{
char *vp;
char *qp;
char *mp;
hex_random_lucm_op (maxbits, &vp, &qp, &mp, Q, b0, res);
set_str (v, vp);
set_str (q, qp);
set_str (m, mp);
free (vp);
free (qp);
free (mp);
}

View File

@@ -0,0 +1,35 @@
/*
Copyright 2011, 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 "../mini-gmp.h"
#include "hex-random.h"
void mini_urandomb (mpz_t, unsigned long);
void mini_rrandomb (mpz_t, unsigned long);
void mini_rrandomb_export (mpz_t r, void *dst, size_t *countp,
int order, size_t size, int endian,
unsigned long bits);
void mini_random_op2 (enum hex_random_op, unsigned long, mpz_t, mpz_t);
void mini_random_op3 (enum hex_random_op, unsigned long, mpz_t, mpz_t, mpz_t);
void mini_random_op4 (enum hex_random_op, unsigned long, mpz_t, mpz_t, mpz_t, mpz_t);
void mini_random_scan_op (enum hex_random_op, unsigned long, mpz_t, mp_bitcnt_t *, mp_bitcnt_t *);
void mini_random_bit_op (enum hex_random_op, unsigned long, mpz_t, mp_bitcnt_t *, mpz_t);
void mini_random_lucm_op (unsigned long, mpz_t, mpz_t, mpz_t,
long *, unsigned long *, int *);

View File

@@ -0,0 +1,143 @@
#! /bin/sh
# Copyright (C) 2000-2002, 2004, 2005, 2011, 2012, 2016, 2020 Niels Möller
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
failed=0
all=0
debug='no'
testflags=''
if [ -z "$srcdir" ] ; then
srcdir=`pwd`
fi
export srcdir
if [ -n "$TEST_SHLIB_DIR" ] ; then
# Prepend to LD_LIBRARY_PATH, if it is alredy set.
LD_LIBRARY_PATH="${TEST_SHLIB_DIR}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
# For MACOS
DYLD_LIBRARY_PATH="$TEST_SHLIB_DIR"
# For Windows
PATH="${TEST_SHLIB_DIR}:${PATH}"
# For Wine
WINEPATH="${TEST_SHLIB_DIR}${WINEPATH:+;$WINEPATH}"
export LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH
export PATH
export WINEPATH
fi
# When used in make rules, we sometimes get the filenames VPATH
# expanded, but usually not.
find_program () {
case "$1" in
*/*)
echo "$1"
;;
*)
if [ -x "$1" ] ; then
echo "./$1"
elif [ -x "$1.exe" ] ; then
echo "./$1.exe"
else
echo "$srcdir/$1"
fi
;;
esac
}
env_program () {
if [ -x "$1" ] ; then
if "$1"; then : ; else
echo FAIL: $1
exit 1
fi
fi
}
test_program () {
testname=`basename "$1" .exe`
testname=`basename "$testname" -test`
if [ -z "$EMULATOR" ] || head -1 "$1" | grep '^#!' > /dev/null; then
"$1" $testflags
else
$EMULATOR "$1" $testflags
fi
case "$?" in
0)
echo PASS: $testname
all=`expr $all + 1`
;;
77)
echo SKIP: $testname
;;
*)
echo FAIL: $testname
failed=`expr $failed + 1`
all=`expr $all + 1`
;;
esac
}
env_program `find_program setup-env`
while test $# != 0
do
case "$1" in
--debug)
debug=yes
;;
-v)
testflags='-v'
;;
-*)
echo >&2 'Unknown option `'"$1'"
exit 1
;;
*)
break
;;
esac
shift
done
# Comment out special handling for zero arguments to support separate
# tests-build/tests-run.
#if [ $# -eq 0 ] ; then
# for f in *-test; do test_program "./$f"; done
#else
for f in "$@" ; do test_program `find_program "$f"`; done
#fi
if [ $failed -eq 0 ] ; then
banner="All $all tests passed"
else
banner="$failed of $all tests failed"
fi
dashes=`echo "$banner" | sed s/./=/g`
echo "$dashes"
echo "$banner"
echo "$dashes"
if [ "x$debug" = xno ] ; then
env_program `find_program teardown-env`
fi
[ "$failed" -eq 0 ]

View File

@@ -0,0 +1,57 @@
/*
Copyright 2012, 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 <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, res, ref;
mpz_init (a);
mpz_init (b);
mpz_init (res);
mpz_init (ref);
for (i = 0; i < COUNT; i++)
{
mini_random_op3 (OP_ADD, MAXBITS, a, b, ref);
mpz_add (res, a, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_add failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (res);
mpz_clear (ref);
}

View File

@@ -0,0 +1,77 @@
/*
Copyright 2012, 2014, 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
#define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, res, ref;
mpz_init (a);
mpz_init (b);
mpz_init_set_ui (res, 5);
mpz_init (ref);
for (i = 0; i < COUNT; i++)
{
mini_random_op3 (OP_MUL, MAXBITS, a, b, ref);
if (i & 1) {
mpz_add (ref, ref, res);
if (mpz_fits_ulong_p (b))
mpz_addmul_ui (res, a, mpz_get_ui (b));
else
mpz_addmul (res, a, b);
} else {
mpz_sub (ref, res, ref);
if (mpz_fits_ulong_p (b))
mpz_submul_ui (res, a, mpz_get_ui (b));
else
mpz_submul (res, a, b);
}
if (mpz_cmp (res, ref))
{
if (i & 1)
fprintf (stderr, "mpz_addmul failed:\n");
else
fprintf (stderr, "mpz_submul failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (res);
mpz_clear (ref);
}

View File

@@ -0,0 +1,104 @@
/*
Copyright 2012, 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, res, ref;
mp_bitcnt_t b;
mpz_init (a);
mpz_init (res);
mpz_init (ref);
for (i = 0; i < COUNT; i++)
{
mini_random_bit_op (OP_SETBIT, MAXBITS, a, &b, ref);
mpz_set (res, a);
mpz_setbit (res, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_setbit failed:\n");
dump ("a", a);
fprintf (stderr, "b: %lu\n", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
if (!mpz_tstbit (res, b))
{
fprintf (stderr, "mpz_tstbit failed (after mpz_setbit):\n");
dump ("res", a);
fprintf (stderr, "b: %lu\n", b);
abort ();
}
mini_random_bit_op (OP_CLRBIT, MAXBITS, a, &b, ref);
mpz_set (res, a);
mpz_clrbit (res, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_clrbit failed:\n");
dump ("a", a);
fprintf (stderr, "b: %lu\n", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
if (mpz_tstbit (res, b))
{
fprintf (stderr, "mpz_tstbit failed (after mpz_clrbit):\n");
dump ("res", a);
fprintf (stderr, "b: %lu\n", b);
abort ();
}
mini_random_bit_op (OP_COMBIT, MAXBITS, a, &b, ref);
mpz_set (res, a);
mpz_com (a, a);
mpz_combit (res, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_combit failed:\n");
dump ("a", a);
fprintf (stderr, "b: %lu\n", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
if (mpz_tstbit (res, b) != mpz_tstbit (a, b))
{
fprintf (stderr, "mpz_tstbit failed (after mpz_combit):\n");
dump ("res", a);
fprintf (stderr, "b: %lu\n", b);
abort ();
}
}
mpz_clear (a);
mpz_clear (res);
mpz_clear (ref);
}

View File

@@ -0,0 +1,283 @@
/* Test mpz_cmp_d and mpz_cmpabs_d.
Copyright 2001-2003, 2005, 2013 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 <math.h>
#include "testutils.h"
/* FIXME: Not sure if the tests here are exhaustive. Ought to try to get
each possible exit from mpz_cmp_d (and mpz_cmpabs_d) exercised. */
#define SGN(n) ((n) > 0 ? 1 : (n) < 0 ? -1 : 0)
void
check_one (const char *name, mpz_srcptr x, double y, int cmp, int cmpabs)
{
int got;
got = mpz_cmp_d (x, y);
if (SGN(got) != cmp)
{
unsigned i;
printf ("mpz_cmp_d wrong (from %s)\n", name);
printf (" got %d\n", got);
printf (" want %d\n", cmp);
fail:
printf (" x=");
mpz_out_str (stdout, 10, x);
printf ("\n y %g\n", y);
printf (" x=0x");
mpz_out_str (stdout, -16, x);
printf ("\n y %g\n", y);
printf (" y");
for (i = 0; i < sizeof(y); i++)
printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
printf ("\n");
abort ();
}
got = mpz_cmpabs_d (x, y);
if (SGN(got) != cmpabs)
{
printf ("mpz_cmpabs_d wrong\n");
printf (" got %d\n", got);
printf (" want %d\n", cmpabs);
goto fail;
}
}
void
check_data (void)
{
static const struct {
const char *x;
double y;
int cmp, cmpabs;
} data[] = {
{ "0", 0.0, 0, 0 },
{ "1", 0.0, 1, 1 },
{ "-1", 0.0, -1, 1 },
{ "1", 0.5, 1, 1 },
{ "-1", -0.5, -1, 1 },
{ "0", 1.0, -1, -1 },
{ "0", -1.0, 1, -1 },
{ "0x1000000000000000000000000000000000000000000000000", 1.0, 1, 1 },
{ "-0x1000000000000000000000000000000000000000000000000", 1.0, -1, 1 },
{ "0", 1e100, -1, -1 },
{ "0", -1e100, 1, -1 },
{ "2", 1.5, 1, 1 },
{ "2", -1.5, 1, 1 },
{ "-2", 1.5, -1, 1 },
{ "-2", -1.5, -1, 1 },
};
mpz_t x;
unsigned i;
mpz_init (x);
for (i = 0; i < numberof (data); i++)
{
mpz_set_str_or_abort (x, data[i].x, 0);
check_one ("check_data", x, data[i].y, data[i].cmp, data[i].cmpabs);
}
mpz_clear (x);
}
/* Equality of integers with up to 53 bits */
void
check_onebits (void)
{
mpz_t x, x2;
double y;
int i;
mpz_init_set_ui (x, 0L);
mpz_init (x2);
for (i = 0; i < 512; i++)
{
mpz_mul_2exp (x, x, 1);
mpz_add_ui (x, x, 1L);
y = mpz_get_d (x);
mpz_set_d (x2, y);
/* stop if any truncation is occurring */
if (mpz_cmp (x, x2) != 0)
break;
check_one ("check_onebits", x, y, 0, 0);
check_one ("check_onebits", x, -y, 1, 0);
mpz_neg (x, x);
check_one ("check_onebits", x, y, -1, 0);
check_one ("check_onebits", x, -y, 0, 0);
mpz_neg (x, x);
}
mpz_clear (x);
mpz_clear (x2);
}
/* With the mpz differing by 1, in a limb position possibly below the double */
void
check_low_z_one (void)
{
mpz_t x;
double y;
unsigned long i;
mpz_init (x);
/* FIXME: It'd be better to base this on the float format. */
#if defined (__vax) || defined (__vax__)
#define LIM 127 /* vax fp numbers have limited range */
#else
#define LIM 512
#endif
for (i = 1; i < LIM; i++)
{
mpz_set_ui (x, 1L);
mpz_mul_2exp (x, x, i);
y = mpz_get_d (x);
check_one ("check_low_z_one", x, y, 0, 0);
check_one ("check_low_z_one", x, -y, 1, 0);
mpz_neg (x, x);
check_one ("check_low_z_one", x, y, -1, 0);
check_one ("check_low_z_one", x, -y, 0, 0);
mpz_neg (x, x);
mpz_sub_ui (x, x, 1);
check_one ("check_low_z_one", x, y, -1, -1);
check_one ("check_low_z_one", x, -y, 1, -1);
mpz_neg (x, x);
check_one ("check_low_z_one", x, y, -1, -1);
check_one ("check_low_z_one", x, -y, 1, -1);
mpz_neg (x, x);
mpz_add_ui (x, x, 2);
check_one ("check_low_z_one", x, y, 1, 1);
check_one ("check_low_z_one", x, -y, 1, 1);
mpz_neg (x, x);
check_one ("check_low_z_one", x, y, -1, 1);
check_one ("check_low_z_one", x, -y, -1, 1);
mpz_neg (x, x);
}
mpz_clear (x);
}
/* Comparing 1 and 1+2^-n. "y" is volatile to make gcc store and fetch it,
which forces it to a 64-bit double, whereas on x86 it would otherwise
remain on the float stack as an 80-bit long double. */
void
check_one_2exp (void)
{
double e;
mpz_t x;
volatile double y;
int i;
mpz_init (x);
e = 1.0;
for (i = 0; i < 128; i++)
{
e /= 2.0;
y = 1.0 + e;
if (y == 1.0)
break;
mpz_set_ui (x, 1L);
check_one ("check_one_2exp", x, y, -1, -1);
check_one ("check_one_2exp", x, -y, 1, -1);
mpz_set_si (x, -1L);
check_one ("check_one_2exp", x, y, -1, -1);
check_one ("check_one_2exp", x, -y, 1, -1);
}
mpz_clear (x);
}
void
check_infinity (void)
{
mpz_t x;
double y = HUGE_VAL;
if (y != 2*y)
return;
mpz_init (x);
/* 0 cmp inf */
mpz_set_ui (x, 0L);
check_one ("check_infinity", x, y, -1, -1);
check_one ("check_infinity", x, -y, 1, -1);
/* 123 cmp inf */
mpz_set_ui (x, 123L);
check_one ("check_infinity", x, y, -1, -1);
check_one ("check_infinity", x, -y, 1, -1);
/* -123 cmp inf */
mpz_set_si (x, -123L);
check_one ("check_infinity", x, y, -1, -1);
check_one ("check_infinity", x, -y, 1, -1);
/* 2^5000 cmp inf */
mpz_set_ui (x, 1L);
mpz_mul_2exp (x, x, 5000L);
check_one ("check_infinity", x, y, -1, -1);
check_one ("check_infinity", x, -y, 1, -1);
/* -2^5000 cmp inf */
mpz_neg (x, x);
check_one ("check_infinity", x, y, -1, -1);
check_one ("check_infinity", x, -y, 1, -1);
mpz_clear (x);
}
void
testmain (int argc, char *argv[])
{
check_data ();
check_onebits ();
check_low_z_one ();
check_one_2exp ();
check_infinity ();
}

View File

@@ -0,0 +1,175 @@
/* 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);
}

View File

@@ -0,0 +1,212 @@
/* test mpz_congruent_p
Copyright 2001, 2002, 2012, 2014 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 "testutils.h"
#define MPZ_SRCPTR_SWAP(x, y) \
do { \
mpz_srcptr __mpz_srcptr_swap__tmp = (x); \
(x) = (y); \
(y) = __mpz_srcptr_swap__tmp; \
} while (0)
void
check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
{
int got;
int swap;
for (swap = 0; swap <= 1; swap++)
{
got = (mpz_congruent_p (a, c, d) != 0);
if (want != got)
{
printf ("mpz_congruent_p wrong\n");
printf (" expected %d got %d\n", want, got);
dump (" a", a);
dump (" c", c);
dump (" d", d);
abort ();
}
#if 0
if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d))
{
unsigned long uc = mpz_get_ui (c);
unsigned long ud = mpz_get_ui (d);
got = (mpz_congruent_ui_p (a, uc, ud) != 0);
if (want != got)
{
printf ("mpz_congruent_ui_p wrong\n");
printf (" expected %d got %d\n", want, got);
dump (" a", a);
printf (" c=%lu\n", uc);
printf (" d=%lu\n", ud);
abort ();
}
}
#endif
MPZ_SRCPTR_SWAP (a, c);
}
}
void
check_data (void)
{
static const struct {
const char *a;
const char *c;
const char *d;
int want;
} data[] = {
/* strict equality mod 0 */
{ "0", "0", "0", 1 },
{ "11", "11", "0", 1 },
{ "3", "11", "0", 0 },
/* anything congruent mod 1 */
{ "0", "0", "1", 1 },
{ "1", "0", "1", 1 },
{ "0", "1", "1", 1 },
{ "123", "456", "1", 1 },
{ "0x123456789123456789", "0x987654321987654321", "1", 1 },
/* csize==1, dsize==2 changing to 1 after stripping 2s */
{ "0x3333333333333333", "0x33333333",
"0x180000000", 1 },
{ "0x33333333333333333333333333333333", "0x3333333333333333",
"0x18000000000000000", 1 },
/* another dsize==2 becoming 1, with opposite signs this time */
{ "0x444444441",
"-0x22222221F",
"0x333333330", 1 },
{ "0x44444444444444441",
"-0x2222222222222221F",
"0x33333333333333330", 1 },
};
mpz_t a, c, d;
unsigned i;
mpz_init (a);
mpz_init (c);
mpz_init (d);
for (i = 0; i < numberof (data); i++)
{
mpz_set_str_or_abort (a, data[i].a, 0);
mpz_set_str_or_abort (c, data[i].c, 0);
mpz_set_str_or_abort (d, data[i].d, 0);
check_one (a, c, d, data[i].want);
}
mpz_clear (a);
mpz_clear (c);
mpz_clear (d);
}
void
check_random (int argc, char *argv[])
{
mpz_t a, c, d, ra, rc;
int i;
int want;
int reps = 10000;
mpz_t bs;
unsigned long size_range, size;
if (argc >= 2)
reps = atoi (argv[1]);
mpz_init (bs);
mpz_init (a);
mpz_init (c);
mpz_init (d);
mpz_init (ra);
mpz_init (rc);
for (i = 0; i < reps; i++)
{
mini_urandomb (bs, 32);
size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
mini_urandomb (bs, size_range);
size = mpz_get_ui (bs);
mini_rrandomb (a, size);
mini_urandomb (bs, 32);
size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
mini_urandomb (bs, size_range);
size = mpz_get_ui (bs);
mini_rrandomb (c, size);
do
{
mini_urandomb (bs, 32);
size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
mini_urandomb (bs, size_range);
size = mpz_get_ui (bs);
mini_rrandomb (d, size);
}
while (mpz_sgn(d) == 0);
mini_urandomb (bs, 3);
if (mpz_tstbit (bs, 0))
mpz_neg (a, a);
if (mpz_tstbit (bs, 1))
mpz_neg (c, c);
if (mpz_tstbit (bs, 2))
mpz_neg (d, d);
mpz_fdiv_r (ra, a, d);
mpz_fdiv_r (rc, c, d);
want = (mpz_cmp (ra, rc) == 0);
check_one (a, c, d, want);
mpz_sub (ra, ra, rc);
mpz_sub (a, a, ra);
check_one (a, c, d, 1);
}
mpz_clear (bs);
mpz_clear (a);
mpz_clear (c);
mpz_clear (d);
mpz_clear (ra);
mpz_clear (rc);
}
void
testmain (int argc, char *argv[])
{
check_data ();
check_random (argc, argv);
}

View File

@@ -0,0 +1,258 @@
/*
Copyright 2012, 2013, 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 <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
typedef void div_qr_func (mpz_t, mpz_t, const mpz_t, const mpz_t);
typedef unsigned long div_qr_ui_func (mpz_t, mpz_t, const mpz_t, unsigned long);
typedef void div_func (mpz_t, const mpz_t, const mpz_t);
typedef unsigned long div_x_ui_func (mpz_t, const mpz_t, unsigned long);
typedef unsigned long div_ui_func (const mpz_t, unsigned long);
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, q, r, rq, rr;
int div_p;
mpz_init (a);
mpz_init (b);
mpz_init (r);
mpz_init (q);
mpz_init (rr);
mpz_init (rq);
for (i = 0; i < COUNT; i++)
{
unsigned j;
for (j = 0; j < 3; j++)
{
static const enum hex_random_op ops[3] = { OP_CDIV, OP_FDIV, OP_TDIV };
static const char name[3] = { 'c', 'f', 't'};
static div_qr_func * const div_qr [3] =
{
mpz_cdiv_qr, mpz_fdiv_qr, mpz_tdiv_qr
};
static div_qr_ui_func * const div_qr_ui[3] =
{
mpz_cdiv_qr_ui, mpz_fdiv_qr_ui, mpz_tdiv_qr_ui
};
static div_func * const div_q [3] =
{
mpz_cdiv_q, mpz_fdiv_q, mpz_tdiv_q
};
static div_x_ui_func * const div_q_ui[3] =
{
mpz_cdiv_q_ui, mpz_fdiv_q_ui, mpz_tdiv_q_ui
};
static div_func * const div_r [3] =
{
mpz_cdiv_r, mpz_fdiv_r, mpz_tdiv_r
};
static div_x_ui_func * const div_r_ui[3] =
{
mpz_cdiv_r_ui, mpz_fdiv_r_ui, mpz_tdiv_r_ui
};
static div_ui_func * const div_ui[3] =
{
mpz_cdiv_ui, mpz_fdiv_ui, mpz_tdiv_ui
};
mini_random_op4 (ops[j], MAXBITS, a, b, rq, rr);
div_qr[j] (q, r, a, b);
if (mpz_cmp (r, rr) || mpz_cmp (q, rq))
{
fprintf (stderr, "mpz_%cdiv_qr failed:\n", name[j]);
dump ("a", a);
dump ("b", b);
dump ("r ", r);
dump ("rref", rr);
dump ("q ", q);
dump ("qref", rq);
abort ();
}
mpz_set_si (q, -5);
div_q[j] (q, a, b);
if (mpz_cmp (q, rq))
{
fprintf (stderr, "mpz_%cdiv_q failed:\n", name[j]);
dump ("a", a);
dump ("b", b);
dump ("q ", q);
dump ("qref", rq);
abort ();
}
mpz_set_ui (r, ~5);
div_r[j] (r, a, b);
if (mpz_cmp (r, rr))
{
fprintf (stderr, "mpz_%cdiv_r failed:\n", name[j]);
dump ("a", a);
dump ("b", b);
dump ("r ", r);
dump ("rref", rr);
abort ();
}
if (j == 0) /* do this once, not for all roundings */
{
div_p = mpz_divisible_p (a, b);
if ((mpz_sgn (r) == 0) ^ (div_p != 0))
{
fprintf (stderr, "mpz_divisible_p failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r ", r);
abort ();
}
}
mpz_set_si (r, -6);
if (j == 0 && mpz_sgn (b) < 0) /* ceil, negative divisor */
{
mpz_mod (r, a, b);
if (mpz_cmp (r, rr))
{
fprintf (stderr, "mpz_mod failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r ", r);
dump ("rref", rr);
abort ();
}
}
if (j == 1 && mpz_sgn (b) > 0) /* floor, positive divisor */
{
mpz_mod (r, a, b);
if (mpz_cmp (r, rr))
{
fprintf (stderr, "mpz_mod failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r ", r);
dump ("rref", rr);
abort ();
}
}
if (mpz_fits_ulong_p (b))
{
unsigned long rl;
mpz_set_si (r, -7);
mpz_set_ui (q, ~7);
rl = div_qr_ui[j] (q, r, a, mpz_get_ui (b));
if (rl != mpz_get_ui (rr)
|| mpz_cmp (r, rr) || mpz_cmp (q, rq))
{
fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
dump ("a", a);
dump ("b", b);
fprintf(stderr, "rl = %lx\n", rl);
dump ("r ", r);
dump ("rref", rr);
dump ("q ", q);
dump ("qref", rq);
abort ();
}
mpz_set_si (q, 3);
rl = div_q_ui[j] (q, a, mpz_get_ui (b));
if (rl != mpz_get_ui (rr) || mpz_cmp (q, rq))
{
fprintf (stderr, "mpz_%cdiv_q_ui failed:\n", name[j]);
dump ("a", a);
dump ("b", b);
fprintf(stderr, "rl = %lx\n", rl);
dump ("rref", rr);
dump ("q ", q);
dump ("qref", rq);
abort ();
}
mpz_set_ui (r, 7);
rl = div_r_ui[j] (r, a, mpz_get_ui (b));
if (rl != mpz_get_ui (rr) || mpz_cmp (r, rr))
{
fprintf (stderr, "mpz_%cdiv_r_ui failed:\n", name[j]);
dump ("a", a);
dump ("b", b);
fprintf(stderr, "rl = %lx\n", rl);
dump ("r ", r);
dump ("rref", rr);
abort ();
}
rl = div_ui[j] (a, mpz_get_ui (b));
if (rl != mpz_get_ui (rr))
{
fprintf (stderr, "mpz_%cdiv_ui failed:\n", name[j]);
dump ("a", a);
dump ("b", b);
fprintf(stderr, "rl = %lx\n", rl);
dump ("rref", rr);
abort ();
}
if (j == 0) /* do this once, not for all roundings */
{
div_p = mpz_divisible_ui_p (a, mpz_get_ui (b));
if ((mpz_sgn (r) == 0) ^ (div_p != 0))
{
fprintf (stderr, "mpz_divisible_ui_p failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r ", r);
abort ();
}
}
if (j == 1) /* floor */
{
mpz_set_si (r, -2);
mpz_mod_ui (r, a, mpz_get_ui (b));
if (mpz_cmp (r, rr))
{
fprintf (stderr, "mpz_mod failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r ", r);
dump ("rref", rr);
abort ();
}
}
}
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (r);
mpz_clear (q);
mpz_clear (rr);
mpz_clear (rq);
}

View File

@@ -0,0 +1,82 @@
/*
Copyright 2012, 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 <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
typedef void div_func (mpz_t, const mpz_t, mp_bitcnt_t);
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, res, ref;
mp_bitcnt_t b;
mpz_init (a);
mpz_init (res);
mpz_init (ref);
for (i = 0; i < COUNT; i++)
{
unsigned j;
for (j = 0; j < 6; j++)
{
static const enum hex_random_op ops[6] =
{
OP_CDIV_Q_2, OP_CDIV_R_2,
OP_FDIV_Q_2, OP_FDIV_R_2,
OP_TDIV_Q_2, OP_TDIV_R_2
};
static const char *name[6] =
{
"cdiv_q", "cdiv_r",
"fdiv_q", "fdiv_r",
"tdiv_q", "tdiv_r"
};
static div_func * const div [6] =
{
mpz_cdiv_q_2exp, mpz_cdiv_r_2exp,
mpz_fdiv_q_2exp, mpz_fdiv_r_2exp,
mpz_tdiv_q_2exp, mpz_tdiv_r_2exp
};
mini_random_bit_op (ops[j], MAXBITS, a, &b, ref);
div[j] (res, a, b);
if (mpz_cmp (ref, res))
{
fprintf (stderr, "mpz_%s_2exp failed:\n", name[j]);
dump ("a", a);
fprintf (stderr, "b: %lu\n", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
}
}
mpz_clear (a);
mpz_clear (res);
mpz_clear (ref);
}

View File

@@ -0,0 +1,232 @@
/*
Copyright 2012, 2013, 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 <limits.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "testutils.h"
#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
mp_bitcnt_t
mpz_mantissasizeinbits (const mpz_t z)
{
return ! mpz_cmp_ui (z, 0) ? 0 :
mpz_sizeinbase (z, 2) - mpz_scan1 (z, 0);
}
#if defined(DBL_MANT_DIG) && FLT_RADIX == 2
int
mpz_get_d_exact_p (const mpz_t z)
{
return mpz_mantissasizeinbits (z) <= DBL_MANT_DIG;
}
#define HAVE_EXACT_P 1
#endif
#define COUNT 10000
void
test_matissa (void)
{
mpz_t x, y;
int i, c;
mpz_init (x);
mpz_init (y);
mini_urandomb (y, 4);
c = i = mpz_get_ui (y);
do {
double d;
int cmp;
mpz_setbit (x, c);
d = mpz_get_d (x);
mpz_set_d (y, d);
if (mpz_cmp_d (y, d) != 0)
{
fprintf (stderr, "mpz_cmp_d (y, d) failed:\n"
"d = %.20g\n"
"i = %i\n"
"c = %i\n",
d, i, c);
abort ();
}
cmp = mpz_cmp (x, y);
#if defined(HAVE_EXACT_P)
if ((mpz_get_d_exact_p (x) != 0) != (cmp == 0))
{
fprintf (stderr, "Not all bits converted:\n"
"d = %.20g\n"
"i = %i\n"
"c = %i\n",
d, i, c);
abort ();
}
#endif
if (cmp < 0)
{
fprintf (stderr, "mpz_get_d failed:\n"
"d = %.20g\n"
"i = %i\n"
"c = %i\n",
d, i, c);
abort ();
}
else if (cmp > 0)
{
if (mpz_cmp_d (x, d) <= 0)
{
fprintf (stderr, "mpz_cmp_d (x, d) failed:\n"
"d = %.20g\n"
"i = %i\n"
"c = %i\n",
d, i, c);
abort ();
}
break;
}
++c;
} while (1);
mpz_clear (x);
mpz_clear (y);
}
#ifndef M_PI
#define M_PI 3.141592653589793238462643383279502884
#endif
static const struct
{
double d;
const char *s;
} values[] = {
{ 0.0, "0" },
{ 0.3, "0" },
{ -0.3, "0" },
{ M_PI, "3" },
{ M_PI*1e15, "b29430a256d21" },
{ -M_PI*1e15, "-b29430a256d21" },
/* 17 * 2^{200} =
27317946752402834684213355569799764242877450894307478200123392 */
{0.2731794675240283468421335556979976424288e62,
"1100000000000000000000000000000000000000000000000000" },
{ 0.0, NULL }
};
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t x;
for (i = 0; values[i].s; i++)
{
char *s;
mpz_init_set_d (x, values[i].d);
s = mpz_get_str (NULL, 16, x);
if (strcmp (s, values[i].s) != 0)
{
fprintf (stderr, "mpz_set_d failed:\n"
"d = %.20g\n"
"s = %s\n"
"r = %s\n",
values[i].d, s, values[i].s);
abort ();
}
testfree (s, strlen(s) + 1);
mpz_clear (x);
}
mpz_init (x);
for (i = 0; i < COUNT; i++)
{
/* Use volatile, to avoid extended precision in floating point
registers, e.g., on m68k and 80387. */
volatile double d, f;
unsigned long m;
int e;
mini_rrandomb (x, GMP_LIMB_BITS);
m = mpz_get_ui (x);
mini_urandomb (x, 8);
e = mpz_get_ui (x) - 100;
d = ldexp ((double) m, e);
mpz_set_d (x, d);
f = mpz_get_d (x);
if (f != floor (d))
{
fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n");
goto dumperror;
}
if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) >= 0))
{
fprintf (stderr, "mpz_cmp_d (x, d) failed:\n");
goto dumperror;
}
f = d + 1.0;
if (f > d && ! (mpz_cmp_d (x, f) < 0))
{
fprintf (stderr, "mpz_cmp_d (x, f) failed:\n");
goto dumperror;
}
d = - d;
mpz_set_d (x, d);
f = mpz_get_d (x);
if (f != ceil (d))
{
fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n");
dumperror:
dump ("x", x);
fprintf (stderr, "m = %lx, e = %i\n", m, e);
fprintf (stderr, "d = %.15g\n", d);
fprintf (stderr, "f = %.15g\n", f);
fprintf (stderr, "f - d = %.5g\n", f - d);
abort ();
}
if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) <= 0))
{
fprintf (stderr, "mpz_cmp_d (x, d) failed:\n");
goto dumperror;
}
f = d - 1.0;
if (f < d && ! (mpz_cmp_d (x, f) > 0))
{
fprintf (stderr, "mpz_cmp_d (x, f) failed:\n");
goto dumperror;
}
}
mpz_clear (x);
test_matissa();
}

View File

@@ -0,0 +1,178 @@
/*
Copyright 2012, 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
/* Called when g is supposed to be gcd(a,b), and g = s a + t b. */
static int
gcdext_valid_p (const mpz_t a, const mpz_t b,
const mpz_t g, const mpz_t s, const mpz_t t)
{
mpz_t ta, tb, r;
/* It's not clear that gcd(0,0) is well defined, but we allow it and
require that gcd(0,0) = 0. */
if (mpz_sgn (g) < 0)
return 0;
if (mpz_sgn (a) == 0)
{
/* Must have g == abs (b). Any value for s is in some sense "correct",
but it makes sense to require that s == 0, t = sgn (b)*/
return mpz_cmpabs (g, b) == 0
&& mpz_sgn (s) == 0 && mpz_cmp_si (t, mpz_sgn (b)) == 0;
}
else if (mpz_sgn (b) == 0)
{
/* Must have g == abs (a), s == sign (a), t = 0 */
return mpz_cmpabs (g, a) == 0
&& mpz_cmp_si (s, mpz_sgn (a)) == 0 && mpz_sgn (t) == 0;
}
if (mpz_sgn (g) <= 0)
return 0;
mpz_init (ta);
mpz_init (tb);
mpz_init (r);
mpz_mul (ta, s, a);
mpz_mul (tb, t, b);
mpz_add (ta, ta, tb);
if (mpz_cmp (ta, g) != 0)
{
fail:
mpz_clear (ta);
mpz_clear (tb);
mpz_clear (r);
return 0;
}
mpz_tdiv_qr (ta, r, a, g);
if (mpz_sgn (r) != 0)
goto fail;
mpz_tdiv_qr (tb, r, b, g);
if (mpz_sgn (r) != 0)
goto fail;
/* Require that 2 |s| < |b/g|, or |s| == 1. */
if (mpz_cmpabs_ui (s, 1) > 0)
{
mpz_mul_2exp (r, s, 1);
if (mpz_cmpabs (r, tb) > 0)
goto fail;
}
/* Require that 2 |t| < |a/g| or |t| == 1*/
if (mpz_cmpabs_ui (t, 1) > 0)
{
mpz_mul_2exp (r, t, 1);
if (mpz_cmpabs (r, ta) > 0)
return 0;
}
mpz_clear (ta);
mpz_clear (tb);
mpz_clear (r);
return 1;
}
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, g, s, t;
mpz_init (a);
mpz_init (b);
mpz_init (g);
mpz_init (s);
mpz_init (t);
for (i = 0; i < COUNT; i++)
{
mini_random_op3 (OP_GCD, MAXBITS, a, b, s);
mpz_gcd (g, a, b);
if (mpz_cmp (g, s))
{
fprintf (stderr, "mpz_gcd failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", g);
dump ("ref", s);
abort ();
}
}
for (i = 0; i < COUNT; i++)
{
unsigned flags;
mini_urandomb (a, 32);
flags = mpz_get_ui (a);
mini_rrandomb (a, MAXBITS);
mini_rrandomb (b, MAXBITS);
if (flags % 37 == 0)
mpz_mul (a, a, b);
if (flags % 37 == 1)
mpz_mul (b, a, b);
if (flags & 1)
mpz_neg (a, a);
if (flags & 2)
mpz_neg (b, b);
mpz_gcdext (g, s, t, a, b);
if (!gcdext_valid_p (a, b, g, s, t))
{
fprintf (stderr, "mpz_gcdext failed:\n");
dump ("a", a);
dump ("b", b);
dump ("g", g);
dump ("s", s);
dump ("t", t);
abort ();
}
mpz_gcd (s, a, b);
if (mpz_cmp (g, s))
{
fprintf (stderr, "mpz_gcd failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", g);
dump ("ref", s);
abort ();
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (g);
mpz_clear (s);
mpz_clear (t);
}

View File

@@ -0,0 +1,99 @@
/*
Copyright 2013 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "testutils.h"
#define MAX_WORDS 20
#define MAX_WORD_SIZE 10
static void
dump_bytes (const char *label, const unsigned char *s, size_t n)
{
size_t i;
fprintf (stderr, "%s:", label);
for (i = 0; i < n; i++)
{
if (i && (i % 16) == 0)
fprintf (stderr, "\n");
fprintf (stderr, " %02x", s[i]);
}
fprintf (stderr, "\n");
}
/* Tests both mpz_import and mpz_export. */
void
testmain (int argc, char **argv)
{
unsigned char input[MAX_WORDS * MAX_WORD_SIZE];
unsigned char output[MAX_WORDS * MAX_WORD_SIZE + 2];
size_t count, in_count, out_count, size;
int endian, order;
mpz_t a, res;
mpz_init (a);
mpz_init (res);
for (size = 0; size <= MAX_WORD_SIZE; size++)
for (count = 0; count <= MAX_WORDS; count++)
for (endian = -1; endian <= 1; endian++)
for (order = -1; order <= 1; order += 2)
{
mini_rrandomb_export (a, input, &in_count,
order, size, endian, size*count * 8);
mpz_import (res, in_count, order, size, endian, 0, input);
if (mpz_cmp (a, res))
{
fprintf (stderr, "mpz_import failed:\n"
"in_count %lu, out_count %lu, endian = %d, order = %d\n",
(unsigned long) in_count, (unsigned long) out_count, endian, order);
dump ("a", a);
dump ("res", res);
abort ();
}
output[0] = 17;
output[1+in_count*size] = 17;
mpz_export (output+1, &out_count, order, size, endian, 0, a);
if (out_count != in_count
|| memcmp (output+1, input, in_count * size)
|| output[0] != 17
|| output[1+in_count*size] != 17)
{
fprintf (stderr, "mpz_export failed:\n"
"in_count %lu, out_count %lu, endian = %d, order = %d\n",
(unsigned long) in_count, (unsigned long) out_count, endian, order);
dump_bytes ("input", input, in_count * size);
dump_bytes ("output", output+1, out_count * size);
if (output[0] != 17)
fprintf (stderr, "Overwrite at -1, value %02x\n", output[0]);
if (output[1+in_count*size] != 17)
fprintf (stderr, "Overwrite at %lu, value %02x\n",
(unsigned long) (in_count*size), output[1+in_count*size]);
abort ();
}
}
mpz_clear (a);
mpz_clear (res);
}

View File

@@ -0,0 +1,141 @@
/*
Copyright 2012, 2016 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 <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
#define COUNT 10000
static void
test_2by1(const mpz_t u)
{
mpz_t m, p, t;
mp_limb_t tl;
mpz_init (p);
assert (mpz_size (u) == 1);
tl = mpn_invert_limb (u->_mp_d[0]);
mpz_roinit_n (t, &tl, 1);
mpz_init_set (m, t);
mpz_setbit (m, GMP_LIMB_BITS);
mpz_mul (p, m, u);
mpz_init (t);
mpz_setbit (t, 2* GMP_LIMB_BITS);
mpz_sub (t, t, p);
/* Should have 0 < B^2 - m u <= u */
if (mpz_sgn (t) <= 0 || mpz_cmp (t, u) > 0)
{
fprintf (stderr, "mpn_invert_limb failed:\n");
dump ("u", u);
dump ("m", m);
dump ("p", p);
dump ("t", t);
abort ();
}
mpz_clear (m);
mpz_clear (p);
mpz_clear (t);
}
static void
test_3by2(const mpz_t u)
{
mpz_t m, p, t;
mp_limb_t tl;
mpz_init (p);
assert (mpz_size (u) == 2);
tl = mpn_invert_3by2 (u->_mp_d[1], u->_mp_d[0]);
mpz_roinit_n (t, &tl, 1);
mpz_init_set (m, t);
mpz_setbit (m, GMP_LIMB_BITS);
mpz_mul (p, m, u);
mpz_init (t);
mpz_setbit (t, 3 * GMP_LIMB_BITS);
mpz_sub (t, t, p);
/* Should have 0 < B^3 - m u <= u */
if (mpz_sgn (t) <= 0 || mpz_cmp (t, u) > 0)
{
fprintf (stderr, "mpn_invert_3by2 failed:\n");
dump ("u", u);
dump ("m", m);
dump ("p", p);
dump ("t", t);
abort ();
}
mpz_clear (m);
mpz_clear (p);
mpz_clear (t);
}
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t u, m, p, t;
mpz_init (u);
mpz_init (m);
mpz_init (p);
mpz_init (t);
/* These values trigger 32-bit overflow of ql in mpn_invert_3by2. */
if (GMP_LIMB_BITS == 64)
{
mpz_set_str (u, "80007fff3ffe0000", 16);
test_2by1 (u);
mpz_set_str (u, "80007fff3ffe000000000000000003ff", 16);
test_3by2 (u);
}
for (i = 0; i < COUNT; i++)
{
mini_urandomb (u, GMP_LIMB_BITS);
mpz_setbit (u, GMP_LIMB_BITS -1);
test_2by1 (u);
}
for (i = 0; i < COUNT; i++)
{
mini_urandomb (u, 2*GMP_LIMB_BITS);
mpz_setbit (u, 2*GMP_LIMB_BITS -1);
test_3by2 (u);
}
mpz_clear (u);
}

View File

@@ -0,0 +1,73 @@
/*
Copyright 2012, 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, g, s;
mpz_init (a);
mpz_init (b);
mpz_init (g);
mpz_init (s);
for (i = 0; i < COUNT; i++)
{
mini_random_op3 (OP_LCM, MAXBITS, a, b, s);
mpz_lcm (g, a, b);
if (mpz_cmp (g, s))
{
fprintf (stderr, "mpz_lcm failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", g);
dump ("ref", s);
abort ();
}
if (mpz_fits_ulong_p (b))
{
mpz_set_si (g, 0);
mpz_lcm_ui (g, a, mpz_get_ui (b));
if (mpz_cmp (g, s))
{
fprintf (stderr, "mpz_lcm_ui failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", g);
dump ("ref", s);
abort ();
}
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (g);
mpz_clear (s);
}

View File

@@ -0,0 +1,111 @@
/*
Copyright 2012, 2014, 2016, 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 <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 100
void
my_mpz_mul (mpz_t r, mpz_srcptr a, mpz_srcptr b)
{
mp_limb_t *tp;
mp_size_t tn, an, bn;
an = mpz_size (a);
bn = mpz_size (b);
assert (an > 0);
assert (bn > 0);
tn = an + bn;
tp = mpz_limbs_write (r, tn);
if (an > bn)
mpn_mul (tp, mpz_limbs_read (a), an, mpz_limbs_read (b), bn);
else
mpn_mul (tp, mpz_limbs_read (b), bn, mpz_limbs_read (a), an);
if (mpz_sgn (a) != mpz_sgn(b))
tn = - tn;
mpz_limbs_finish (r, tn);
}
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, res, ref;
mpz_init (a);
mpz_init (b);
mpz_init (res);
mpz_init (ref);
for (i = 0; i < COUNT; i++)
{
mini_random_op3 (OP_MUL, MAXBITS, a, b, ref);
if (mpz_sgn(ref) == 0)
/* my_mpz_mul requires a != 0, b != 0 */
continue;
my_mpz_mul (res, a, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "my_mpz_mul failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
/* The following test exploits a side-effect of my_mpz_mul: res
points to a buffer with at least an+bn limbs, and the limbs
above the result are zeroed. */
if (mpz_size (b) > 0 && mpz_getlimbn (res, mpz_size(a)) != mpz_limbs_read (res) [mpz_size(a)])
{
fprintf (stderr, "getlimbn - limbs_read differ.\n");
abort ();
}
if ((i % 4 == 0) && mpz_size (res) > 1)
{
mpz_realloc2 (res, 1);
if (mpz_cmp_ui (res, 0))
{
fprintf (stderr, "mpz_realloc2 did not clear res.\n");
abort ();
}
mpz_limbs_finish (ref, 0);
if (mpz_cmp_d (ref, 0))
{
fprintf (stderr, "mpz_limbs_finish did not clear res.\n");
abort ();
}
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (res);
mpz_clear (ref);
}

View File

@@ -0,0 +1,112 @@
/*
Copyright 2012, 2013 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
void
testlogops (int count)
{
int i;
mpz_t a, b, res, ref;
mp_bitcnt_t c;
mpz_init (a);
mpz_init (b);
mpz_init (res);
mpz_init (ref);
for (i = 0; i < count; i++)
{
mini_random_op3 (OP_AND, MAXBITS, a, b, ref);
mpz_and (res, a, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_and failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
mini_random_op3 (OP_IOR, MAXBITS, a, b, ref);
mpz_ior (res, a, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_ior failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
mini_random_op3 (OP_XOR, MAXBITS, a, b, ref);
mpz_xor (res, a, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_xor failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
if (i % 8) {
c = 0;
mpz_mul_2exp (res, res, i % 8);
} else if (mpz_sgn (res) >= 0) {
c = mpz_odd_p (res) != 0;
mpz_tdiv_q_2exp (res, res, 1);
} else {
c = (~ (mp_bitcnt_t) 0) - 3;
mpz_set_ui (res, 11 << ((i >> 3)%4)); /* set 3 bits */
}
if (mpz_popcount (res) + c != mpz_hamdist (a, b))
{
fprintf (stderr, "mpz_popcount(r) + %lu and mpz_hamdist(a,b) differ:\n", c);
dump ("a", a);
dump ("b", b);
dump ("r", res);
fprintf (stderr, "mpz_popcount(r) = %lu:\n", mpz_popcount (res));
fprintf (stderr, "mpz_hamdist(a,b) = %lu:\n", mpz_hamdist (a, b));
abort ();
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (res);
mpz_clear (ref);
}
void
testmain (int argc, char **argv)
{
testhalves (COUNT*2/3, testlogops);
testlogops (COUNT/3);
}

View File

@@ -0,0 +1,98 @@
/* Tests the (internal) function mpz_lucas_mod
Copyright 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "testutils.h"
#define MAXBITS 100
#define COUNT 1000
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t m, vr, qr, vm, qm, vt;
int resm, resr;
long Q;
unsigned long b0;
mpz_init (m);
mpz_init (vr);
mpz_init (qr);
mpz_init (vm);
mpz_init (qm);
mpz_init (vt);
for (i = 0; i < COUNT; i++)
{
mini_random_lucm_op (MAXBITS, vr, qr, m, &Q, &b0, &resr);
if (b0 == 0)
{
fprintf (stderr, "lucas_mod: test disabled (%u tests done).\n", i);
break;
}
resm = mpz_lucas_mod (vm, qm, Q, b0, m);
if (resr != resm)
{
if (resm != 0 || mpz_cmp_ui (vm, 0) != 0)
{
fprintf (stderr, "mpz_lucas_mod wrong return value (%d != %d):\n", resr, resm);
fprintf (stderr, "Q = %ld , b0 = %lu\n", Q, b0);
dump ("m", m);
dump ("vm", vm);
dump ("qm", qm);
abort ();
}
}
else if (resm == 0)
{
mpz_abs (vr, vr);
mpz_sub (vt, m, vr);
mpz_abs (vm, vm);
mpz_mod (qm, qm, m);
if (mpz_cmp_ui (qr, 0) < 0)
mpz_add (qr, qr, m);
if (mpz_cmp (qm, qr) != 0 ||
(mpz_cmp (vm, vr) != 0 && mpz_cmp (vm, vt) != 0))
{
fprintf (stderr, "mpz_lucas_mod error:\n");
fprintf (stderr, "Q = %ld , b0 = %lu\n", Q, b0);
dump ("m", m);
dump ("vm", vm);
dump ("vr", vr);
dump ("vt", vt);
dump ("qm", qm);
dump ("qr", qr);
abort ();
}
}
}
mpz_clear (m);
mpz_clear (vr);
mpz_clear (qr);
mpz_clear (vm);
mpz_clear (qm);
mpz_clear (vt);
}

View File

@@ -0,0 +1,204 @@
/*
Copyright 2012, 2013, 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 <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#include "../mini-mpq.h"
#define MAXBITS 300
#define COUNT 10000
static void
_mpq_set_zz (mpq_t q, mpz_t n, mpz_t d)
{
if (mpz_fits_ulong_p (d) && mpz_fits_slong_p (n))
{
mpq_set_si (q, mpz_get_si (n), mpz_get_ui (d));
}
else if (mpz_fits_ulong_p (d) && mpz_fits_ulong_p (n))
{
mpq_set_ui (q, mpz_get_ui (n), mpz_get_ui (d));
}
else
{
mpq_set_num (q, n);
mpq_set_den (q, d);
}
mpq_canonicalize (q);
}
void
testcmpui ()
{
unsigned d1, d2, n1, n2;
mpq_t q1, q2;
mpq_init (q1);
mpq_init (q2);
for (d1 = 1; d1 < 6; d1 += 2)
for (n1 = 1; n1 < 6; n1 *= 2)
{
mpq_set_ui (q1, n1, d1);
for (d2 = 1; d2 < 6; d2 += 2)
for (n2 = 1; n2 < 6; n2 *= 2)
{
int fres = mpq_cmp_ui (q1, n2, d2);
int ref = (d1*n2 < d2*n1) - (d1*n2 > d2*n1);
mpq_set_ui (q2, n2, d2);
if ((!ref) != mpq_equal (q1, q2))
{
fprintf (stderr, "mpz_equal failed: %i / %i = %i / %i ? %i\n", n1, d1, n2, d2, ref);
abort ();
}
if (ref != fres)
{
fprintf (stderr, "mpz_cmp_ui failed: %i / %i = %i / %i ? %i != %i\n", n1, d1, n2, d2, ref, fres);
abort ();
}
}
}
mpq_clear (q1);
mpq_clear (q2);
}
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, q, r, c;
mpq_t rr, ii, ff;
int tst;
testcmpui ();
mpz_init (a);
mpz_init (b);
mpz_init (r);
mpz_init (q);
mpz_init (c);
mpq_init (rr);
mpq_init (ff);
mpq_init (ii);
for (i = 0; i < COUNT; i++)
{
mini_random_op4 (OP_TDIV, MAXBITS, a, b, q, r);
_mpq_set_zz (rr, a, b);
_mpq_set_zz (ff, r, b);
mpq_set_z (ii, q);
mpz_set_q (c, rr);
if (mpz_cmp (c, q))
{
fprintf (stderr, "mpz_set_q failed:\n");
dump ("a", a);
dump ("b", b);
dump ("c", c);
dump ("q", q);
abort ();
}
if ((mpz_sgn (r) != 0) ^ (mpz_cmp_ui (mpq_denref (rr), 1) != 0))
{
fprintf (stderr, "mpq_canonicalize failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", r);
dump ("D", mpq_denref (rr));
abort ();
}
if (i & 1)
{
if (mpz_fits_slong_p (q))
tst = mpq_cmp_si (rr, mpz_get_si (q), 1);
else if (mpz_fits_ulong_p (q))
tst = mpq_cmp_ui (rr, mpz_get_ui (q), 1);
else
tst = mpq_cmp_z (rr, q);
if (mpz_sgn (b) < 0)
tst = - tst;
if ((tst != mpz_sgn (r)) && ((tst < 0 && mpz_sgn (r) >= 0) || (tst > 0 && mpz_sgn (r) <= 0)))
{
fprintf (stderr, "mpq_cmp ii failed: %i %i\n", tst, mpz_sgn (r));
dump ("a", a);
dump ("b", b);
dump ("r", r);
dump ("q", q);
abort ();
}
}
else
{
if (mpz_fits_ulong_p (b) && mpz_fits_slong_p (r))
tst = mpq_cmp_si (rr, mpz_get_si (r), mpz_get_ui (b));
else if (mpz_fits_ulong_p (b) && mpz_fits_ulong_p (r))
tst = mpq_cmp_ui (rr, mpz_get_ui (r), mpz_get_ui (b));
else
tst = mpq_cmp (rr, ff);
if ((tst != mpz_sgn (q)) && ((tst < 0 && mpz_sgn (q) >= 0) || (tst > 0 && mpz_sgn (q) <= 0)))
{
fprintf (stderr, "mpq_cmp ff failed: %i %i\n", tst, mpz_sgn (q));
dump ("a", a);
dump ("b", b);
dump ("r", r);
dump ("q", q);
abort ();
}
}
if (i & 1)
{
mpq_sub (rr, rr, ff);
}
else
{
mpq_neg (ff, ff);
mpq_add (rr, ff, rr);
}
if (!mpq_equal (ii, rr))
{
fprintf (stderr, "mpq_%s failed:\n", (i & 1) ? "sub" : "add");
dump ("a", a);
dump ("b", b);
dump ("r", r);
dump ("q", q);
abort ();
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (r);
mpz_clear (q);
mpz_clear (c);
mpq_clear (rr);
mpq_clear (ff);
mpq_clear (ii);
}

View File

@@ -0,0 +1,211 @@
/* Test mpq_set_d.
Copyright 2001-2003, 2005, 2013, 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 <math.h>
#include <float.h>
#include <limits.h>
#include "testutils.h"
#include "../mini-mpq.h"
#define COUNT 2000
mp_bitcnt_t
mpz_mantissasizeinbits (const mpz_t z)
{
return ! mpz_cmp_ui (z, 0) ? 0 :
mpz_sizeinbase (z, 2) - mpz_scan1 (z, 0);
}
int
mpz_abspow2_p (const mpz_t z)
{
return mpz_mantissasizeinbits (z) == 1;
}
mp_bitcnt_t
mpq_mantissasizeinbits (const mpq_t q)
{
if (! mpz_abspow2_p (mpq_denref (q)))
return ~ (mp_bitcnt_t) 0;
return mpz_mantissasizeinbits (mpq_numref (q));
}
#if defined(DBL_MANT_DIG) && FLT_RADIX == 2
int
mpz_get_d_exact_p (const mpz_t z)
{
return mpz_mantissasizeinbits (z) <= DBL_MANT_DIG;
}
int
mpq_get_d_exact_p (const mpq_t q)
{
return mpq_mantissasizeinbits (q) <= DBL_MANT_DIG;
}
#define HAVE_EXACT_P 1
#endif
void
check_random (void)
{
unsigned i;
mpz_t x;
mpq_t y, z;
mpz_init (x);
mpq_init (y);
mpq_init (z);
for (i = 0; i < COUNT; i++)
{
/* Use volatile, to avoid extended precision in floating point
registers, e.g., on m68k and 80387. */
volatile double d, f;
unsigned long m;
int e, c;
mini_rrandomb (x, CHAR_BIT * sizeof (unsigned long));
m = mpz_get_ui (x);
mini_urandomb (x, 8);
e = mpz_get_ui (x) - 128;
d = ldexp ((double) m, e);
mpq_set_d (y, d);
f = mpq_get_d (y);
if (f != d)
{
fprintf (stderr, "mpq_set_d/mpq_get_d failed:\n");
goto dumperror;
}
d = - d;
mpq_neg (y, y);
mpq_set_d (z, d);
f = mpq_get_d (z);
if (f != d || !mpq_equal (y, z))
{
fprintf (stderr, "mpq_set_d/mpq_get_d failed:\n");
dumperror:
dump ("ny", mpq_numref (y));
dump ("dy", mpq_denref (y));
fprintf (stderr, "m = %lx, e = %i\n", m, e);
fprintf (stderr, "d = %.35g\n", d);
fprintf (stderr, "f = %.35g\n", f);
fprintf (stderr, "f - d = %.35g\n", f - d);
abort ();
}
mini_rrandomb (x, CHAR_BIT * sizeof (unsigned long));
m = mpz_get_ui (x);
mini_urandomb (x, 8);
e = mpz_get_ui (x) - 128;
d = ldexp ((double) m, e);
mpq_set_d (y, d);
if (i == 0)
mpq_neg (z, y);
mpq_add (y, y, z);
mpq_set_d (z, mpq_get_d (y));
f = mpq_get_d (z);
c = mpq_cmp (y, z);
#if defined(HAVE_EXACT_P)
if (mpq_get_d_exact_p (y) ? c != 0 : (f > 0 ? c <= 0 : c >= 0))
#else
if (f > 0 ? c < 0 : c > 0)
#endif
{
fprintf (stderr, "mpq_get_d/mpq_set_d failed: %i %i\n", i, c);
goto dumperror;
}
}
mpz_clear (x);
mpq_clear (y);
mpq_clear (z);
}
void
check_data (void)
{
static const struct {
double y;
long int n;
unsigned long d;
} data[] = {
{ 0.0, 0, 1 },
{ 1.0, 1, 1 },
{ -1.0, -1, 1 },
{ -1.5, -3, 2 },
{-1.25, -5, 4 },
{0.125, 1, 8 },
{24685,24685,1},
{-9876,-9876,1},
{463.5, 927,2},
{1234.5/8192, 2469, 16384 },
{-543.0/1024, -543, 1024 },
{9876.5/ 512, 19753, 1024 },
{9753.0/ 128, 9753, 128 },
{-789.0/ 32, -789, 32 },
{4.580078125, 2345, 512 },
};
mpq_t x, r;
unsigned i;
double d;
mpq_init (x);
mpq_init (r);
for (i = 0; i < numberof (data); i++)
{
mpq_set_d (x, data[i].y);
mpq_set_si (r, data[i].n, data[i].d);
mpq_canonicalize (r);
if (!mpq_equal (x, r))
{
fprintf (stderr, "mpq_set_d failed: %li / %lu != %g\n", data[i].n, data[i].d, data[i].y);
abort ();
}
d = mpq_get_d (r);
if (d != data[i].y)
{
fprintf (stderr, "mpq_get_d failed: %li / %lu != %g\n", data[i].n, data[i].d, data[i].y);
abort ();
}
}
mpq_clear (x);
mpq_clear (r);
}
void
testmain (int argc, char *argv[])
{
check_data ();
check_random ();
}

View File

@@ -0,0 +1,176 @@
/*
Copyright 2012, 2013, 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 <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#include "../mini-mpq.h"
#define MAXBITS 300
#define COUNT 10000
static void
_mpq_set_zz (mpq_t q, mpz_t n, mpz_t d)
{
if (mpz_fits_ulong_p (d) && mpz_fits_slong_p (n))
{
mpq_set_si (q, mpz_get_si (n), mpz_get_ui (d));
}
else if (mpz_fits_ulong_p (d) && mpz_fits_ulong_p (n))
{
mpq_set_ui (q, mpz_get_ui (n), mpz_get_ui (d));
}
else
{
mpq_set_num (q, n);
mpq_set_den (q, d);
}
mpq_canonicalize (q);
}
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t an, bn, rn, ad, bd, rd;
mpq_t aq, bq, refq, resq;
mpz_init (an);
mpz_init (bn);
mpz_init (rn);
mpz_init (ad);
mpz_init (bd);
mpz_init (rd);
mpq_init (aq);
mpq_init (bq);
mpq_init (refq);
mpq_init (resq);
for (i = 0; i < COUNT; i++)
{
mini_random_op3 (OP_MUL, MAXBITS, an, bn, rn);
do {
mini_random_op3 (OP_MUL, MAXBITS, ad, bd, rd);
} while (mpz_sgn (rd) == 0);
_mpq_set_zz (aq, an, ad);
_mpq_set_zz (bq, bn, bd);
_mpq_set_zz (refq, rn, rd);
mpq_mul (resq, aq, bq);
if (!mpq_equal (resq, refq))
{
fprintf (stderr, "mpq_mul failed [%i]:\n", i);
dump ("an", an);
dump ("ad", ad);
dump ("bn", bn);
dump ("bd", bd);
dump ("refn", rn);
dump ("refd", rd);
dump ("resn", mpq_numref (resq));
dump ("resd", mpq_denref (resq));
abort ();
}
if (mpq_sgn (refq) != 0)
{
mpq_set_ui (resq, ~6, 8);
mpq_inv (aq, aq);
mpq_div (resq, aq, bq);
mpq_inv (resq, resq);
if (!mpq_equal (resq, refq))
{
fprintf (stderr, "mpq_div failed [%i]:\n", i);
dump ("an", an);
dump ("ad", ad);
dump ("bn", bn);
dump ("bd", bd);
dump ("refn", rn);
dump ("refd", rd);
dump ("resn", mpq_numref (resq));
dump ("resd", mpq_denref (resq));
abort ();
}
mpq_swap (bq, aq);
mpq_div (resq, aq, bq);
if (!mpq_equal (resq, refq))
{
fprintf (stderr, "mpq_swap failed [%i]:\n", i);
dump ("an", an);
dump ("ad", ad);
dump ("bn", bn);
dump ("bd", bd);
dump ("refn", rn);
dump ("refd", rd);
dump ("resn", mpq_numref (resq));
dump ("resd", mpq_denref (resq));
abort ();
}
}
mpq_set (resq, aq);
mpq_neg (bq, aq);
mpq_abs (refq, aq);
if (mpq_equal (refq, resq))
mpq_add (resq, refq, bq);
else
mpq_add (resq, refq, resq);
mpq_set_ui (refq, 0, 1);
if (!mpq_equal (resq, refq))
{
fprintf (stderr, "mpq_abs failed [%i]:\n", i);
dump ("an", an);
dump ("ad", ad);
dump ("resn", mpq_numref (resq));
dump ("resd", mpq_denref (resq));
abort ();
}
mpq_mul (resq, aq, aq);
mpq_mul (refq, aq, bq); /* now bq = - aq */
mpq_neg (refq, refq);
if (!mpq_equal (resq, refq))
{
fprintf (stderr, "mpq_mul(sqr) failed [%i]:\n", i);
dump ("an", an);
dump ("ad", ad);
dump ("bn", bn);
dump ("bd", bd);
dump ("refn", rn);
dump ("refd", rd);
dump ("resn", mpq_numref (resq));
dump ("resd", mpq_denref (resq));
abort ();
}
}
mpz_clear (an);
mpz_clear (bn);
mpz_clear (rn);
mpz_clear (ad);
mpz_clear (bd);
mpz_clear (rd);
mpq_clear (aq);
mpq_clear (bq);
mpq_clear (refq);
mpq_clear (resq);
}

View File

@@ -0,0 +1,138 @@
/*
Copyright 2012, 2013, 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 <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#include "../mini-mpq.h"
#define MAXBITS 300
#define COUNT 10000
static void
_mpq_set_zz (mpq_t q, mpz_t n, mpz_t d)
{
if (mpz_fits_ulong_p (d) && mpz_fits_slong_p (n))
{
mpq_set_si (q, mpz_get_si (n), mpz_get_ui (d));
}
else if (mpz_fits_ulong_p (d) && mpz_fits_ulong_p (n))
{
mpq_set_ui (q, mpz_get_ui (n), mpz_get_ui (d));
}
else
{
mpq_set_num (q, n);
mpq_set_den (q, d);
}
mpq_canonicalize (q);
}
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, t;
mpq_t aq, rq, tq;
mp_bitcnt_t e;
long int e2, t1, t2;
mpz_init (a);
mpz_init (b);
mpz_init (t);
mpq_init (aq);
mpq_init (rq);
mpq_init (tq);
for (i = 0; i < COUNT; i++)
{
do {
mini_random_bit_op (OP_COMBIT, MAXBITS, a, &e, b);
} while (mpz_sgn (a) == 0 || mpz_sgn (b) == 0);
_mpq_set_zz (aq, a, b);
e2 = mpz_scan1 (a, 0);
e2-= mpz_scan1 (b, 0);
mpq_mul_2exp (rq, aq, e);
t1 = mpz_scan1 (mpq_numref (rq), 0);
t2 = mpz_scan1 (mpq_denref (rq), 0);
mpq_neg (tq, rq);
mpq_div (tq, aq, tq);
mpq_get_den (t, tq);
if (e2 + e != t1 - t2 || (t2 != 0 && t1 != 0) || mpz_scan1 (t, 0) != e
|| mpz_sizeinbase (t, 2) - 1 != e || mpz_cmp_si (mpq_numref (tq), -1) != 0)
{
fprintf (stderr, "mpq_mul_2exp failed: %lu\n", e);
dump ("na", a);
dump ("da", b);
dump ("nr", mpq_numref (rq));
dump ("dr", mpq_denref (rq));
abort ();
}
mpq_div_2exp (rq, aq, e);
t1 = mpz_scan1 (mpq_numref (rq), 0);
t2 = mpz_scan1 (mpq_denref (rq), 0);
mpq_div (aq, aq, rq);
mpq_get_num (t, aq);
if (e2 != t1 - t2 + e || (t2 != 0 && t1 != 0) || mpz_scan1 (t, 0) != e
|| mpz_sizeinbase (t, 2) - 1 != e || mpz_cmp_ui (mpq_denref (aq), 1) != 0)
{
fprintf (stderr, "mpq_div_2exp failed: %lu\n", e);
fprintf (stderr, "%li %li %lu %zu\n", e2, t2, mpz_scan1 (t, 0), mpz_sizeinbase (t, 2));
dump ("na", a);
dump ("da", b);
dump ("nr", mpq_numref (rq));
dump ("dr", mpq_denref (rq));
abort ();
}
mpq_set_ui (aq, 0, 1);
mpq_set_ui (rq, 6, 7);
mpq_set (tq, aq);
mpq_div_2exp (rq, aq, e);
if (!mpq_equal (tq, rq))
{
fprintf (stderr, "mpq_div_2exp failed on zero: %lu\n", e);
abort ();
}
mpq_set_ui (rq, 7, 6);
mpq_mul_2exp (rq, aq, e);
if (!mpq_equal (rq, tq))
{
fprintf (stderr, "mpq_mul_2exp failed on zero: %lu\n", e);
abort ();
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (t);
mpq_clear (aq);
mpq_clear (rq);
mpq_clear (tq);
}

View File

@@ -0,0 +1,263 @@
/*
Copyright 2012-2014, 2016, 2018, 2020 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 <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "testutils.h"
#include "../mini-mpq.h"
#define MAXBITS 400
#define COUNT 2000
#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
#define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
static void
test_small (void)
{
struct {
const char *input;
const char *decimal;
} data[] = {
{ "1832407/3", "1832407/3" },
{ " 2763959/6", "2763959/6 " },
{ "4 981 999 / 1 8", "4981999/18" },
{ "10\t73981/30 ", "1073981/30" },
{ "958 544 /1", "00958544/01" },
{ "-0", "0000" },
{ " -000 ", "0/ 1" },
{ "0704436/011", "231710/9" },
/* Check the case of large number of leading zeros. */
{ "0000000000000000000000000/1", "0/0000000000000000000000001" },
{ "000000000000000704436/000011", "0000000000000000231710/00009" },
{ " 012/ 02503517", "10/689999" },
{ "0b 10/0 1312143", "2/365667" },
{ "-03 274062/0x1", "-882738/1" },
{ "012\t242", "005282" },
{ "9/0b11010111110010001111", "9/883855" },
{ "022/ 0b11001010010100001", "18/103585" },
{ "-0b101010110011101111/0x12", "-175343/18" },
{ "-05/0b 111 1111 0110 1110 0110", "-5/521958" },
{ "0b 011 111 110 111 001 000 011/0b00110", "1044035/6" },
{ " 0x53dfc", "343548" },
{ "-0x00012/0x000fA019", "-18/1024025" },
{ "0x 642d1", "410321" },
{ "0x5 8067/0Xa", "360551/10" },
{ "-0xd6Be6/3", "-879590/3" },
{ "\t0B1110000100000000011", "460803" },
{ "0B\t1111110010010100101", "517285" },
{ "-0x 00 2d/0B1\t010111101101110100", "-45/359284" },
{ "-0B101\t1001101111111001", "-367609" },
{ "0B10001001010111110000/0xf", "562672/15" },
{ "0Xe4B7e/1", "936830" },
{ "0X1E4bf/0X1", "124095" },
{ "-0Xfdb90/05", "-1039248/5" },
{ "0b010/0X7fc47", "2/523335" },
{ "15/0X8167c", "15/530044" },
/* Some invalid inputs */
{ "", NULL },
{ "0x", NULL },
{ "0b", NULL },
{ "0z", NULL },
{ "-", NULL },
{ "/0x ", NULL },
{ "0|1", NULL },
{ "/", NULL },
{ "0ab", NULL },
{ "10x0", NULL },
{ "1/0xxab", NULL },
{ "0/ab", NULL },
{ "0/#", NULL },
{ "$foo/1", NULL },
{ NULL, NULL }
};
unsigned i;
mpq_t a, b;
mpq_init (a);
mpq_init (b);
for (i = 0; data[i].input; i++)
{
int res = mpq_set_str (a, data[i].input, 0);
if (data[i].decimal)
{
if (res != 0)
{
fprintf (stderr, "mpq_set_str returned -1, input: %s\n",
data[i].input);
abort ();
}
if (mpq_set_str (b, data[i].decimal, 10) != 0)
{
fprintf (stderr, "mpq_set_str returned -1, decimal input: %s\n",
data[i].input);
abort ();
}
if (!mpq_equal (a, b))
{
fprintf (stderr, "mpq_set_str failed for input: %s\n",
data[i].input);
dump ("got_num", mpq_numref (a));
dump ("got_den", mpq_denref (a));
dump ("ref_num", mpq_numref (b));
dump ("ref_den", mpq_denref (b));
abort ();
}
}
else if (res != -1)
{
fprintf (stderr, "mpq_set_str returned %d, invalid input: %s\n",
res, data[i].input);
abort ();
}
}
mpq_clear (a);
mpq_clear (b);
}
void
testmain (int argc, char **argv)
{
unsigned i;
char *ap;
char *bp;
char *rp;
size_t rn;
mpq_t a, b;
FILE *tmp;
test_small ();
mpq_init (a);
mpq_init (b);
tmp = tmpfile ();
if (!tmp)
fprintf (stderr,
"Failed to create temporary file. Skipping mpq_out_str tests.\n");
if (mpq_out_str (tmp, 63, a) != 0)
{
printf ("mpq_out_str did not return 0 (error) with base > 62\n");
abort ();
}
if (mpq_out_str (tmp, -37, a) != 0)
{
printf ("mpq_out_str did not return 0 (error) with base < -37\n");
abort ();
}
for (i = 0; i < COUNT/60; i++)
{
int base;
for (base = 2; base <= 62; ++base)
{
hex_mpq_random_str_op (MAXBITS, (i&1 || base > 36) ? base: -base, &ap, &rp);
if (mpq_set_str (a, ap, 16) != 0)
{
fprintf (stderr, "mpq_set_str failed on input %s\n", ap);
abort ();
}
rn = strlen (rp);
bp = mpq_get_str (NULL, (i&1 || base > 36) ? base: -base, a);
if (strcmp (bp, rp))
{
fprintf (stderr, "mpz_get_str failed:\n");
dump ("a_num", mpq_numref (a));
dump ("a_den", mpq_denref (a));
fprintf (stderr, "b = %s\n", bp);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", rp);
abort ();
}
/* Just a few tests with file i/o. */
if (tmp && i < 20)
{
size_t tn;
rewind (tmp);
tn = mpq_out_str (tmp, (i&1 || base > 36) ? base: -base, a);
if (tn != rn)
{
fprintf (stderr, "mpq_out_str, bad return value:\n");
dump ("a_num", mpq_numref (a));
dump ("a_den", mpq_denref (a));
fprintf (stderr, "r = %s\n", rp);
fprintf (stderr, " base %d, correct size %u, got %u\n",
base, (unsigned) rn, (unsigned)tn);
abort ();
}
rewind (tmp);
memset (bp, 0, rn);
tn = fread (bp, 1, rn, tmp);
if (tn != rn)
{
fprintf (stderr,
"fread failed, expected %lu bytes, got only %lu.\n",
(unsigned long) rn, (unsigned long) tn);
abort ();
}
if (memcmp (bp, rp, rn) != 0)
{
fprintf (stderr, "mpq_out_str failed:\n");
dump ("a_num", mpq_numref (a));
dump ("a_den", mpq_denref (a));
fprintf (stderr, "b = %s\n", bp);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", rp);
abort ();
}
}
mpq_set_str (b, rp, base);
if (!mpq_equal (a, b))
{
fprintf (stderr, "mpq_set_str failed:\n");
fprintf (stderr, "r = %s\n", rp);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", ap);
fprintf (stderr, " base = 16\n");
dump ("b_num", mpq_numref (b));
dump ("b_den", mpq_denref (b));
dump ("r_num", mpq_numref (a));
dump ("r_den", mpq_denref (a));
abort ();
}
free (ap);
free (rp);
testfree (bp, strlen(bp) + 1);
}
}
mpq_clear (a);
mpq_clear (b);
}

View File

@@ -0,0 +1,113 @@
/*
Copyright 2012, 2014, 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
#define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, res, res_ui, ref, tz;
mp_limb_t t[2*MAXLIMBS];
mp_size_t an;
mpz_init (a);
mpz_init (b);
mpz_init (res);
mpz_init (res_ui);
mpz_init (ref);
for (i = 0; i < COUNT; i++)
{
mini_random_op3 (OP_MUL, MAXBITS, a, b, ref);
mpz_mul (res, a, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_mul failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
if (mpz_size (a) == mpz_size (b))
{
memset (t, 0x55, sizeof(t));
an = mpz_size (a);
if (an > 0)
{
mpn_mul_n (t, a->_mp_d, b->_mp_d, an);
mpz_roinit_n (tz, t, 2*an);
if (mpz_cmpabs (tz, ref))
{
fprintf (stderr, "mpn_mul_n failed:\n");
dump ("a", a);
dump ("b", b);
dump ("ref", ref);
abort ();
}
}
}
if (mpz_fits_slong_p (b)) {
mpz_mul_si (res_ui, a, mpz_get_si (b));
if (mpz_cmp (res_ui, ref))
{
fprintf (stderr, "mpz_mul_si failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res_ui);
dump ("ref", ref);
abort ();
}
}
mini_random_op2 (OP_SQR, MAXBITS, a, ref);
an = mpz_size (a);
if (an > 0)
{
memset (t, 0x33, sizeof(t));
mpn_sqr (t, mpz_limbs_read (a), an);
mpz_roinit_n (tz, t, 2*an);
if (mpz_cmp (tz, ref))
{
fprintf (stderr, "mpn (squaring) failed:\n");
dump ("a", a);
dump ("ref", ref);
abort ();
}
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (res);
mpz_clear (res_ui);
mpz_clear (ref);
}

View File

@@ -0,0 +1,87 @@
/*
Copyright 2012, 2022, 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 1000
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t b, e, m, res, ref;
mpz_init (b);
mpz_init (e);
mpz_init (m);
mpz_init (res);
mpz_init (ref);
for (i = 0; i < COUNT; i++)
{
mini_random_op4 (OP_POWM, MAXBITS, b, e, m, ref);
mpz_powm (res, b, e, m);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_powm failed:\n");
dump ("b", b);
dump ("e", e);
dump ("m", m);
dump ("r", res);
dump ("ref", ref);
abort ();
}
}
/* res >= 0, come from the random choices above, */
if (mpz_cmp_ui (res, 1) <= 0) /* if too small, */
mpz_add_ui (res, res, 9); /* add an arbitrary value. */
mpz_set_ui (e, 0);
/* Test the case m^0 (mod m), expect 1 (m is greater than 1). */
mpz_powm (res, res, e, res);
if (mpz_cmp_ui (res, 1) != 0)
{
fprintf (stderr, "mpz_powm failed: b=m, e=0; 1 expected,\n");
dump ("m", res);
dump ("r", res);
abort ();
}
/* Now res is 1. */
/* Test the case 1^0 (mod 1), expect 0. */
mpz_powm (res, res, e, res);
if (mpz_size (res))
{
fprintf (stderr, "mpz_powm failed: b=1, e=0, m=1; 0 expected,\n");
dump ("r", res);
abort ();
}
mpz_clear (b);
mpz_clear (e);
mpz_clear (m);
mpz_clear (res);
mpz_clear (ref);
}

View File

@@ -0,0 +1,183 @@
/* test mpz_probab_prime_p
Copyright 2001, 2002, 2004, 2011, 2012, 2014, 2016 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 "testutils.h"
static int
isprime (unsigned long int t)
{
unsigned long int q, r, d;
if (t < 32)
return (0xa08a28acUL >> t) & 1;
if ((t & 1) == 0)
return 0;
if (t % 3 == 0)
return 0;
if (t % 5 == 0)
return 0;
if (t % 7 == 0)
return 0;
for (d = 11;;)
{
q = t / d;
r = t - q * d;
if (q < d)
return 1;
if (r == 0)
break;
d += 2;
q = t / d;
r = t - q * d;
if (q < d)
return 1;
if (r == 0)
break;
d += 4;
}
return 0;
}
static void
check_one (mpz_srcptr n, int want)
{
int got;
got = mpz_probab_prime_p (n, 25);
/* "definitely prime" is fine if we only wanted "probably prime" */
if (got == 2 && want == 1)
want = 2;
if (got != want)
{
printf ("mpz_probab_prime_p\n");
dump (" n ", n);
printf (" got =%d", got);
printf (" want=%d\n", want);
abort ();
}
}
static void
check_pn (mpz_ptr n, int want)
{
check_one (n, want);
mpz_neg (n, n);
check_one (n, want);
}
static void
check_small (void)
{
mpz_t n;
long i;
mpz_init (n);
for (i = 0; i < 1700; i++)
{
mpz_set_si (n, i);
check_pn (n, isprime (i));
}
mpz_clear (n);
}
void
check_composites (void)
{
int i;
int reps = 1000;
mpz_t a, b, n, bs;
unsigned long size_range, size;
mpz_init (a);
mpz_init (b);
mpz_init (n);
mpz_init (bs);
for (i = 0; i < reps; i++)
{
mini_urandomb (bs, 16);
size_range = mpz_get_ui (bs) % 10 + 1; /* 0..1024 bit operands */
mini_urandomb (bs, size_range);
size = mpz_get_ui (bs);
mini_rrandomb (a, size);
mini_urandomb (bs, size_range);
size = mpz_get_ui (bs);
mini_rrandomb (b, size);
/* Exclude trivial factors */
if (mpz_cmp_ui (a, 1) == 0)
mpz_set_ui (a, 2);
if (mpz_cmp_ui (b, 1) == 0)
mpz_set_ui (b, 2);
mpz_mul (n, a, b);
check_pn (n, 0);
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (n);
mpz_clear (bs);
}
static void
check_primes (void)
{
static const char * const primes[] = {
"2", "17", "65537",
/* diffie-hellman-group1-sha1, also "Well known group 2" in RFC
2412, 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } */
"0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
"FFFFFFFFFFFFFFFF",
NULL
};
mpz_t n;
int i;
mpz_init (n);
for (i = 0; primes[i]; i++)
{
mpz_set_str_or_abort (n, primes[i], 0);
check_one (n, 1);
}
mpz_clear (n);
}
void
testmain (int argc, char *argv[])
{
check_small ();
check_composites ();
check_primes ();
}

View File

@@ -0,0 +1,663 @@
/* Test that routines allow reusing a source variable as destination.
Copyright 1996, 1999-2002, 2009, 2012 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "testutils.h"
#define COUNT 100
void dump3 (const char *, mpz_t, mpz_t, mpz_t);
void mpz_check_format (const mpz_t);
typedef void (*dss_func) (mpz_t, const mpz_t, const mpz_t);
typedef void (*dsi_func) (mpz_t, const mpz_t, unsigned long int);
typedef unsigned long int (*dsi_div_func) (mpz_t, const mpz_t, unsigned long int);
typedef unsigned long int (*ddsi_div_func) (mpz_t, mpz_t, const mpz_t, unsigned long int);
typedef void (*ddss_div_func) (mpz_t, mpz_t, const mpz_t, const mpz_t);
typedef void (*ds_func) (mpz_t, const mpz_t);
void
mpz_xinvert (mpz_t r, const mpz_t a, const mpz_t b)
{
int res;
res = mpz_invert (r, a, b);
if (res == 0)
mpz_set_ui (r, 0);
}
dss_func dss_funcs[] =
{
mpz_add, mpz_sub, mpz_mul,
mpz_cdiv_q, mpz_cdiv_r, mpz_fdiv_q, mpz_fdiv_r, mpz_tdiv_q, mpz_tdiv_r,
mpz_xinvert,
mpz_gcd, mpz_lcm, mpz_and, mpz_ior, mpz_xor
};
const char *dss_func_names[] =
{
"mpz_add", "mpz_sub", "mpz_mul",
"mpz_cdiv_q", "mpz_cdiv_r", "mpz_fdiv_q", "mpz_fdiv_r", "mpz_tdiv_q", "mpz_tdiv_r",
"mpz_xinvert",
"mpz_gcd", "mpz_lcm", "mpz_and", "mpz_ior", "mpz_xor"
};
char dss_func_division[] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
dsi_func dsi_funcs[] =
{
/* Don't change order here without changing the code in main(). */
mpz_add_ui, mpz_mul_ui, mpz_sub_ui,
mpz_fdiv_q_2exp, mpz_fdiv_r_2exp,
mpz_cdiv_q_2exp, mpz_cdiv_r_2exp,
mpz_tdiv_q_2exp, mpz_tdiv_r_2exp,
mpz_mul_2exp,
mpz_pow_ui
};
const char *dsi_func_names[] =
{
"mpz_add_ui", "mpz_mul_ui", "mpz_sub_ui",
"mpz_fdiv_q_2exp", "mpz_fdiv_r_2exp",
"mpz_cdiv_q_2exp", "mpz_cdiv_r_2exp",
"mpz_tdiv_q_2exp", "mpz_tdiv_r_2exp",
"mpz_mul_2exp",
"mpz_pow_ui"
};
dsi_div_func dsi_div_funcs[] =
{
mpz_cdiv_q_ui, mpz_cdiv_r_ui,
mpz_fdiv_q_ui, mpz_fdiv_r_ui,
mpz_tdiv_q_ui, mpz_tdiv_r_ui
};
const char *dsi_div_func_names[] =
{
"mpz_cdiv_q_ui", "mpz_cdiv_r_ui",
"mpz_fdiv_q_ui", "mpz_fdiv_r_ui",
"mpz_tdiv_q_ui", "mpz_tdiv_r_ui"
};
ddsi_div_func ddsi_div_funcs[] =
{
mpz_cdiv_qr_ui,
mpz_fdiv_qr_ui,
mpz_tdiv_qr_ui
};
const char *ddsi_div_func_names[] =
{
"mpz_cdiv_qr_ui",
"mpz_fdiv_qr_ui",
"mpz_tdiv_qr_ui"
};
ddss_div_func ddss_div_funcs[] =
{
mpz_cdiv_qr,
mpz_fdiv_qr,
mpz_tdiv_qr
};
const char *ddss_div_func_names[] =
{
"mpz_cdiv_qr",
"mpz_fdiv_qr",
"mpz_tdiv_qr"
};
ds_func ds_funcs[] =
{
mpz_abs, mpz_com, mpz_neg, mpz_sqrt
};
const char *ds_func_names[] =
{
"mpz_abs", "mpz_com", "mpz_neg", "mpz_sqrt"
};
#define FAIL(class,indx,op1,op2,op3) \
do { \
class##_funcs[indx] = 0; \
dump3 (class##_func_names[indx], op1, op2, op3); \
failures++; \
} while (0)
#define FAIL2(fname,op1,op2,op3) \
do { \
dump3 (#fname, op1, op2, op3); \
failures++; \
} while (0)
void
testmain (int argc, char **argv)
{
unsigned i;
int pass, reps = COUNT;
mpz_t in1, in2, in3;
unsigned long int in2i;
mp_size_t size;
mpz_t res1, res2, res3;
mpz_t ref1, ref2, ref3;
mpz_t t;
unsigned long int r1, r2;
long failures = 0;
mpz_t bs;
unsigned long bsi, size_range;
mpz_init (bs);
mpz_init (in1);
mpz_init (in2);
mpz_init (in3);
mpz_init (ref1);
mpz_init (ref2);
mpz_init (ref3);
mpz_init (res1);
mpz_init (res2);
mpz_init (res3);
mpz_init (t);
for (pass = 1; pass <= reps; pass++)
{
mini_urandomb (bs, 32);
size_range = mpz_get_ui (bs) % 12 + 2;
mini_urandomb (bs, size_range);
size = mpz_get_ui (bs);
mini_rrandomb (in1, size);
mini_urandomb (bs, size_range);
size = mpz_get_ui (bs);
mini_rrandomb (in2, size);
mini_urandomb (bs, size_range);
size = mpz_get_ui (bs);
mini_rrandomb (in3, size);
mini_urandomb (bs, 3);
bsi = mpz_get_ui (bs);
if ((bsi & 1) != 0)
mpz_neg (in1, in1);
if ((bsi & 2) != 0)
mpz_neg (in2, in2);
if ((bsi & 4) != 0)
mpz_neg (in3, in3);
for (i = 0; i < numberof (dss_funcs); i++)
{
if (dss_funcs[i] == 0)
continue;
if (dss_func_division[i] && mpz_sgn (in2) == 0)
continue;
(dss_funcs[i]) (ref1, in1, in2);
mpz_check_format (ref1);
mpz_set (res1, in1);
(dss_funcs[i]) (res1, res1, in2);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL (dss, i, in1, in2, NULL);
mpz_set (res1, in2);
(dss_funcs[i]) (res1, in1, res1);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL (dss, i, in1, in2, NULL);
}
for (i = 0; i < numberof (ddss_div_funcs); i++)
{
if (ddss_div_funcs[i] == 0)
continue;
if (mpz_sgn (in2) == 0)
continue;
(ddss_div_funcs[i]) (ref1, ref2, in1, in2);
mpz_check_format (ref1);
mpz_check_format (ref2);
mpz_set (res1, in1);
(ddss_div_funcs[i]) (res1, res2, res1, in2);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
FAIL (ddss_div, i, in1, in2, NULL);
mpz_set (res2, in1);
(ddss_div_funcs[i]) (res1, res2, res2, in2);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
FAIL (ddss_div, i, in1, in2, NULL);
mpz_set (res1, in2);
(ddss_div_funcs[i]) (res1, res2, in1, res1);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
FAIL (ddss_div, i, in1, in2, NULL);
mpz_set (res2, in2);
(ddss_div_funcs[i]) (res1, res2, in1, res2);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
FAIL (ddss_div, i, in1, in2, NULL);
}
for (i = 0; i < numberof (ds_funcs); i++)
{
if (ds_funcs[i] == 0)
continue;
if (strcmp (ds_func_names[i], "mpz_sqrt") == 0
&& mpz_sgn (in1) < 0)
continue;
(ds_funcs[i]) (ref1, in1);
mpz_check_format (ref1);
mpz_set (res1, in1);
(ds_funcs[i]) (res1, res1);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL (ds, i, in1, in2, NULL);
}
in2i = mpz_get_ui (in2);
for (i = 0; i < numberof (dsi_funcs); i++)
{
if (dsi_funcs[i] == 0)
continue;
if (strcmp (dsi_func_names[i], "mpz_fdiv_q_2exp") == 0)
/* Limit exponent to something reasonable for the division
functions. Without this, we'd normally shift things off
the end and just generate the trivial values 1, 0, -1. */
in2i %= 0x1000;
if (strcmp (dsi_func_names[i], "mpz_mul_2exp") == 0)
/* Limit exponent more for mpz_mul_2exp to save time. */
in2i %= 0x100;
if (strcmp (dsi_func_names[i], "mpz_pow_ui") == 0)
/* Limit exponent yet more for mpz_pow_ui to save time. */
in2i %= 0x10;
(dsi_funcs[i]) (ref1, in1, in2i);
mpz_check_format (ref1);
mpz_set (res1, in1);
(dsi_funcs[i]) (res1, res1, in2i);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL (dsi, i, in1, in2, NULL);
}
if (in2i != 0) /* Don't divide by 0. */
{
for (i = 0; i < numberof (dsi_div_funcs); i++)
{
r1 = (dsi_div_funcs[i]) (ref1, in1, in2i);
mpz_check_format (ref1);
mpz_set (res1, in1);
r2 = (dsi_div_funcs[i]) (res1, res1, in2i);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0 || r1 != r2)
FAIL (dsi_div, i, in1, in2, NULL);
}
for (i = 0; i < numberof (ddsi_div_funcs); i++)
{
r1 = (ddsi_div_funcs[i]) (ref1, ref2, in1, in2i);
mpz_check_format (ref1);
mpz_set (res1, in1);
r2 = (ddsi_div_funcs[i]) (res1, res2, res1, in2i);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
FAIL (ddsi_div, i, in1, in2, NULL);
mpz_set (res2, in1);
(ddsi_div_funcs[i]) (res1, res2, res2, in2i);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
FAIL (ddsi_div, i, in1, in2, NULL);
}
}
if (mpz_sgn (in1) >= 0)
{
mpz_sqrtrem (ref1, ref2, in1);
mpz_check_format (ref1);
mpz_check_format (ref2);
mpz_set (res1, in1);
mpz_sqrtrem (res1, res2, res1);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
mpz_set (res2, in1);
mpz_sqrtrem (res1, res2, res2);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
}
if (mpz_sgn (in1) >= 0)
{
mpz_root (ref1, in1, in2i % 0x1000 + 1);
mpz_check_format (ref1);
mpz_set (res1, in1);
mpz_root (res1, res1, in2i % 0x1000 + 1);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_root, in1, in2, NULL);
}
if (mpz_sgn (in1) >= 0)
{
mpz_rootrem (ref1, ref2, in1, in2i % 0x1000 + 1);
mpz_check_format (ref1);
mpz_check_format (ref2);
mpz_set (res1, in1);
mpz_rootrem (res1, res2, res1, in2i % 0x1000 + 1);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
FAIL2 (mpz_rootrem, in1, in2, NULL);
mpz_set (res2, in1);
mpz_rootrem (res1, res2, res2, in2i % 0x1000 + 1);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
FAIL2 (mpz_rootrem, in1, in2, NULL);
}
if (pass < reps / 2) /* run fewer tests since gcdext lots of time */
{
mpz_gcdext (ref1, ref2, ref3, in1, in2);
mpz_check_format (ref1);
mpz_check_format (ref2);
mpz_check_format (ref3);
mpz_set (res1, in1);
mpz_gcdext (res1, res2, res3, res1, in2);
mpz_check_format (res1);
mpz_check_format (res2);
mpz_check_format (res3);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res2, in1);
mpz_gcdext (res1, res2, res3, res2, in2);
mpz_check_format (res1);
mpz_check_format (res2);
mpz_check_format (res3);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res3, in1);
mpz_gcdext (res1, res2, res3, res3, in2);
mpz_check_format (res1);
mpz_check_format (res2);
mpz_check_format (res3);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res1, in2);
mpz_gcdext (res1, res2, res3, in1, res1);
mpz_check_format (res1);
mpz_check_format (res2);
mpz_check_format (res3);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res2, in2);
mpz_gcdext (res1, res2, res3, in1, res2);
mpz_check_format (res1);
mpz_check_format (res2);
mpz_check_format (res3);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res3, in2);
mpz_gcdext (res1, res2, res3, in1, res3);
mpz_check_format (res1);
mpz_check_format (res2);
mpz_check_format (res3);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res1, in1);
mpz_gcdext (res1, res2, NULL, res1, in2);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res2, in1);
mpz_gcdext (res1, res2, NULL, res2, in2);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res1, in2);
mpz_gcdext (res1, res2, NULL, in1, res1);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
mpz_set (res2, in2);
mpz_gcdext (res1, res2, NULL, in1, res2);
mpz_check_format (res1);
mpz_check_format (res2);
if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
|| mpz_cmp (ref3, res3) != 0)
FAIL2 (mpz_gcdext, in1, in2, NULL);
}
/* Don't run mpz_powm for huge exponents or when undefined. */
if (mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0
&& (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3)))
{
mpz_powm (ref1, in1, in2, in3);
mpz_check_format (ref1);
mpz_set (res1, in1);
mpz_powm (res1, res1, in2, in3);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_powm, in1, in2, in3);
mpz_set (res1, in2);
mpz_powm (res1, in1, res1, in3);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_powm, in1, in2, in3);
mpz_set (res1, in3);
mpz_powm (res1, in1, in2, res1);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_powm, in1, in2, in3);
}
/* Don't run mpz_powm_ui when undefined. */
if (mpz_sgn (in3) != 0)
{
mpz_powm_ui (ref1, in1, in2i, in3);
mpz_check_format (ref1);
mpz_set (res1, in1);
mpz_powm_ui (res1, res1, in2i, in3);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_powm_ui, in1, in2, in3);
mpz_set (res1, in3);
mpz_powm_ui (res1, in1, in2i, res1);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_powm_ui, in1, in2, in3);
}
{
r1 = mpz_gcd_ui (ref1, in1, in2i);
mpz_check_format (ref1);
mpz_set (res1, in1);
r2 = mpz_gcd_ui (res1, res1, in2i);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_gcd_ui, in1, in2, NULL);
}
#if 0
if (mpz_cmp_ui (in2, 1L) > 0 && mpz_sgn (in1) != 0)
{
/* Test mpz_remove */
mpz_remove (ref1, in1, in2);
mpz_check_format (ref1);
mpz_set (res1, in1);
mpz_remove (res1, res1, in2);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_remove, in1, in2, NULL);
mpz_set (res1, in2);
mpz_remove (res1, in1, res1);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_remove, in1, in2, NULL);
}
#endif
if (mpz_sgn (in2) != 0)
{
/* Test mpz_divexact */
mpz_mul (t, in1, in2);
mpz_divexact (ref1, t, in2);
mpz_check_format (ref1);
mpz_set (res1, t);
mpz_divexact (res1, res1, in2);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_divexact, t, in2, NULL);
mpz_set (res1, in2);
mpz_divexact (res1, t, res1);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_divexact, t, in2, NULL);
}
#if 0
if (mpz_sgn (in2) > 0)
{
/* Test mpz_divexact_gcd, same as mpz_divexact */
mpz_mul (t, in1, in2);
mpz_divexact_gcd (ref1, t, in2);
mpz_check_format (ref1);
mpz_set (res1, t);
mpz_divexact_gcd (res1, res1, in2);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_divexact_gcd, t, in2, NULL);
mpz_set (res1, in2);
mpz_divexact_gcd (res1, t, res1);
mpz_check_format (res1);
if (mpz_cmp (ref1, res1) != 0)
FAIL2 (mpz_divexact_gcd, t, in2, NULL);
}
#endif
}
if (failures != 0)
{
fprintf (stderr, "mpz/reuse: %ld error%s\n", failures, "s" + (failures == 1));
exit (1);
}
mpz_clear (bs);
mpz_clear (in1);
mpz_clear (in2);
mpz_clear (in3);
mpz_clear (ref1);
mpz_clear (ref2);
mpz_clear (ref3);
mpz_clear (res1);
mpz_clear (res2);
mpz_clear (res3);
mpz_clear (t);
}
void
dump3 (const char *name, mpz_t in1, mpz_t in2, mpz_t in3)
{
printf ("failure in %s (", name);
mpz_out_str (stdout, -16, in1);
if (in2 != NULL)
{
printf (" ");
mpz_out_str (stdout, -16, in2);
}
if (in3 != NULL)
{
printf (" ");
mpz_out_str (stdout, -16, in3);
}
printf (")\n");
}
void
mpz_check_format (const mpz_t x)
{
mp_size_t n = x ->_mp_size;
if (n < 0)
n = - n;
if (n > x->_mp_alloc)
{
fprintf (stderr, "mpz_t size exceeds allocation!\n");
abort ();
}
if (n > 0 && x->_mp_d[n-1] == 0)
{
fprintf (stderr, "Unnormalized mpz_t!\n");
abort ();
}
}

View File

@@ -0,0 +1,95 @@
/*
Copyright 2012, 2013 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
/* Called when s is supposed to be floor(root(u,z)), and r = u - s^z */
static int
rootrem_valid_p (const mpz_t u, const mpz_t s, const mpz_t r, unsigned long z)
{
mpz_t t;
mpz_init (t);
if (mpz_fits_ulong_p (s))
mpz_ui_pow_ui (t, mpz_get_ui (s), z);
else
mpz_pow_ui (t, s, z);
mpz_sub (t, u, t);
if ((mpz_sgn (t) != mpz_sgn(u) && mpz_sgn (t) != 0) || mpz_cmp (t, r) != 0)
{
mpz_clear (t);
return 0;
}
if (mpz_sgn (s) > 0)
mpz_add_ui (t, s, 1);
else
mpz_sub_ui (t, s, 1);
mpz_pow_ui (t, t, z);
if (mpz_cmpabs (t, u) <= 0)
{
mpz_clear (t);
return 0;
}
mpz_clear (t);
return 1;
}
void
testmain (int argc, char **argv)
{
unsigned i;
unsigned long e;
mpz_t u, s, r, bs;
mpz_init (u);
mpz_init (s);
mpz_init (r);
mpz_init (bs);
for (i = 0; i < COUNT; i++)
{
mini_rrandomb (u, MAXBITS);
mini_rrandomb (bs, 12);
e = mpz_getlimbn (bs, 0) % mpz_sizeinbase (u, 2) + 1;
if ((e & 1) && (mpz_getlimbn (bs, 0) & (1L<<10)))
mpz_neg (u, u);
mpz_rootrem (s, r, u, e);
if (!rootrem_valid_p (u, s, r, e))
{
fprintf (stderr, "mpz_rootrem(%lu-th) failed:\n", e);
dump ("u", u);
dump ("root", s);
dump ("rem", r);
abort ();
}
}
mpz_clear (bs);
mpz_clear (u);
mpz_clear (s);
mpz_clear (r);
}

View File

@@ -0,0 +1,90 @@
/*
Copyright 2012, 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a;
mp_bitcnt_t b, res, ref;
mpz_init (a);
for (i = 0; i < COUNT; i++)
{
mini_random_scan_op (OP_SCAN0, MAXBITS, a, &b, &ref);
res = mpz_scan0 (a, b);
if (res != ref)
{
fprintf (stderr, "mpz_scan0 failed:\n");
dump ("a", a);
fprintf (stderr, "b: %lu\n", b);
fprintf (stderr, "r: %lu\n", res);
fprintf (stderr, "ref: %lu\n", ref);
abort ();
}
if (mpz_sgn (a) > 0 && ref < mpz_sizeinbase (a, 2))
{
res = mpn_scan0 (a->_mp_d, b);
if (res != ref)
{
fprintf (stderr, "mpn_scan0 failed:\n");
dump ("a", a);
fprintf (stderr, "b: %lu\n", b);
fprintf (stderr, "r: %lu\n", res);
fprintf (stderr, "ref: %lu\n", ref);
abort ();
}
}
mini_random_scan_op (OP_SCAN1, MAXBITS, a, &b, &ref);
res = mpz_scan1 (a, b);
if (res != ref)
{
fprintf (stderr, "mpz_scan1 failed:\n");
dump ("a", a);
fprintf (stderr, "b: %lu\n", b);
fprintf (stderr, "r: %lu\n", res);
fprintf (stderr, "ref: %lu\n", ref);
abort ();
}
if (mpz_sgn (a) > 0 && ref != ~ (mp_bitcnt_t) 0)
{
res = mpn_scan1 (a->_mp_d, b);
if (res != ref)
{
fprintf (stderr, "mpn_scan1 failed:\n");
dump ("a", a);
fprintf (stderr, "b: %lu\n", b);
fprintf (stderr, "r: %lu\n", res);
fprintf (stderr, "ref: %lu\n", ref);
abort ();
}
}
}
mpz_clear (a);
}

View File

@@ -0,0 +1,348 @@
/* Exercise some mpz_..._si functions.
Copyright 2013, 2016, 2020 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 <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include "testutils.h"
/* Always called with sz fitting in a signed long, and si is the
corresponding value. */
int
check_si (const mpz_t sz, long si)
{
mpz_t t;
/* Checks on sz/si */
if ((mpz_cmp_si (sz, si)) != 0)
{
printf ("mpz_cmp_si (sz, %ld) != 0.\n", si);
return 0;
}
if (mpz_get_si (sz) != si)
{
printf ("mpz_get_si (sz) != %ld.\n", si);
return 0;
}
mpz_init_set_si (t, si);
if (mpz_cmp (t, sz) != 0)
{
printf ("mpz_init_set_si (%ld) failed.\n", si);
printf (" got="); mpz_out_str (stdout, 10, t); printf ("\n");
return 0;
}
mpz_clear (t);
return 1;
}
/* Called with mpz_cmp (sz, oz) == c. If sz fits in a signed long,
si is the coresponding value, and similarly for oz and oi. */
void
check_si_cmp (const mpz_t sz, const mpz_t oz, long si, long oi, int c)
{
if (mpz_cmp (sz, oz) != c)
{
printf ("mpz_cmp (sz, oz) != %i.\n", c);
goto fail;
}
if (mpz_fits_slong_p (sz))
{
if (!check_si (sz, si))
goto fail;
if (mpz_cmp_si (oz, si) != -c)
{
printf ("mpz_cmp_si (oz, %ld) != %i.\n", si, -c);
goto fail;
}
}
else
{
if (mpz_cmp_si (sz, si) != c)
{
printf ("mpz_cmp_si (sz, %ld) != %i.\n", si, c);
goto fail;
}
if (mpz_cmp_si (sz, -c) != c)
{
printf ("mpz_cmp_si (sz, %i) != %i.\n", -c, c);
goto fail;
}
}
if (mpz_fits_slong_p (oz))
{
if (!check_si (oz, oi))
goto fail;
if (mpz_cmp_si (sz, oi) != c)
{
printf ("mpz_cmp_si (sz, %ld) != %i.\n", oi, c);
goto fail;
}
}
return;
fail:
printf (" sz="); mpz_out_str (stdout, 10, sz); printf ("\n");
printf (" si=%ld\n", si);
printf (" oz="); mpz_out_str (stdout, 10, oz); printf ("\n");
printf (" oi=%ld\n", si);
abort ();
}
void
try_op_si (int c)
{
long si, oi;
mpz_t sz, oz;
unsigned overflow_count;
si = c;
mpz_init_set_si (sz, si);
oi = si;
mpz_init_set (oz, sz);
/* To get a few tests with operands straddling the border, don't
stop at the very first operand exceeding a signed long. */
for (overflow_count = 0; overflow_count < 10; )
{
/* c * 2^k */
mpz_mul_2exp (sz, sz, 1);
if (mpz_fits_slong_p (sz))
si *= 2;
else
overflow_count++;
check_si_cmp (sz, oz, si, oi, c);
/* c * (2^k + 1) */
if (c == -1)
mpz_sub_ui (oz, sz, 1);
else
mpz_add_ui (oz, sz, 1);
if (mpz_fits_slong_p (oz))
oi = si + c;
else
overflow_count++;
check_si_cmp (oz, sz, oi, si, c);
/* c * (2^K - 1) */
mpz_mul_si (oz, sz, 2*c);
if (c == -1)
mpz_ui_sub (oz, 1, oz); /* oz = sz * 2 + 1 */
else
mpz_sub_ui (oz, oz, 1); /* oz = sz * 2 - 1 */
if (mpz_fits_slong_p (oz))
oi = (si - c) * 2 + c;
else
overflow_count++;
check_si_cmp (oz, sz, oi, si, c);
};
mpz_clear (sz);
mpz_clear (oz);
}
void
try_fits_slong_p (void)
{
mpz_t x;
mpz_init_set_si (x, LONG_MAX);
if (!mpz_fits_slong_p (x))
{
printf ("mpz_fits_slong_p (LONG_MAX) false!\n");
abort ();
}
mpz_add_ui (x, x, 1);
if (mpz_fits_slong_p (x))
{
printf ("mpz_fits_slong_p (LONG_MAX + 1) true!\n");
abort ();
}
mpz_set_si (x, LONG_MIN);
if (!mpz_fits_slong_p (x))
{
printf ("mpz_fits_slong_p (LONG_MIN) false!\n");
abort ();
}
mpz_sub_ui (x, x, 1);
if (mpz_fits_slong_p (x))
{
printf ("mpz_fits_slong_p (LONG_MIN - 1) true!\n");
abort ();
}
mpz_clear (x);
}
void
try_fits_utype_p (void)
{
mpz_t x;
mpz_init (x);
if (!mpz_fits_ulong_p (x))
{
printf ("mpz_fits_ulong_p (0) false!\n");
abort ();
}
if (!mpz_fits_uint_p (x))
{
printf ("mpz_fits_uint_p (0) false!\n");
abort ();
}
if (!mpz_fits_ushort_p (x))
{
printf ("mpz_fits_udhort_p (0) false!\n");
abort ();
}
mpz_set_si (x, -1);
if (mpz_fits_ulong_p (x))
{
printf ("mpz_fits_ulong_p (- 1) true!\n");
abort ();
}
if (mpz_fits_uint_p (x))
{
printf ("mpz_fits_uint_p (- 1) true!\n");
abort ();
}
if (mpz_fits_ushort_p (x))
{
printf ("mpz_fits_ushort_p (- 1) true!\n");
abort ();
}
mpz_set_ui (x, ULONG_MAX);
if (!mpz_fits_ulong_p (x))
{
printf ("mpz_fits_ulong_p (ULONG_MAX) false!\n");
abort ();
}
mpz_add_ui (x, x, 1);
if (mpz_fits_ulong_p (x))
{
printf ("mpz_fits_ulong_p (ULONG_MAX + 1) true!\n");
abort ();
}
mpz_set_ui (x, UINT_MAX);
if (!mpz_fits_uint_p (x))
{
printf ("mpz_fits_uint_p (UINT_MAX) false!\n");
abort ();
}
mpz_add_ui (x, x, 1);
if (mpz_fits_uint_p (x))
{
printf ("mpz_fits_uint_p (UINT_MAX + 1) true!\n");
abort ();
}
mpz_set_ui (x, USHRT_MAX);
if (!mpz_fits_ushort_p (x))
{
printf ("mpz_fits_ushort_p (USHRT_MAX) false!\n");
abort ();
}
mpz_add_ui (x, x, 1);
if (mpz_fits_ushort_p (x))
{
printf ("mpz_fits_ushort_p (USHRT_MAX + 1) true!\n");
abort ();
}
mpz_clear (x);
}
void
try_fits_sint_p (void)
{
mpz_t x;
mpz_init_set_si (x, INT_MAX);
if (!mpz_fits_sint_p (x))
{
printf ("mpz_fits_sint_p (INT_MAX) false!\n");
abort ();
}
mpz_add_ui (x, x, 1);
if (mpz_fits_sint_p (x))
{
printf ("mpz_fits_sint_p (INT_MAX + 1) true!\n");
abort ();
}
mpz_set_si (x, INT_MIN);
if (!mpz_fits_sint_p (x))
{
printf ("mpz_fits_sint_p (INT_MIN) false!\n");
abort ();
}
mpz_sub_ui (x, x, 1);
if (mpz_fits_sint_p (x))
{
printf ("mpz_fits_sint_p (INT_MIN - 1) true!\n");
abort ();
}
mpz_clear (x);
}
void
try_fits_sshort_p (void)
{
mpz_t x;
mpz_init_set_si (x, SHRT_MAX);
if (!mpz_fits_sshort_p (x))
{
printf ("mpz_fits_sshort_p (SHRT_MAX) false!\n");
abort ();
}
mpz_add_ui (x, x, 1);
if (mpz_fits_sshort_p (x))
{
printf ("mpz_fits_sshort_p (SHRT_MAX + 1) true!\n");
abort ();
}
mpz_set_si (x, SHRT_MIN);
if (!mpz_fits_sshort_p (x))
{
printf ("mpz_fits_sshort_p (SHRT_MIN) false!\n");
abort ();
}
mpz_sub_ui (x, x, 1);
if (mpz_fits_sshort_p (x))
{
printf ("mpz_fits_sshort_p (SHRT_MIN - 1) true!\n");
abort ();
}
mpz_clear (x);
}
void
testmain (int argc, char *argv[])
{
try_fits_slong_p ();
try_fits_sint_p ();
try_fits_sshort_p ();
try_fits_utype_p ();
try_op_si (-1);
try_op_si (1);
}

View File

@@ -0,0 +1,181 @@
/*
Copyright 2012, 2014, 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 <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 9000
/* Called when s is supposed to be floor(sqrt(u)), and r = u - s^2 */
static int
sqrtrem_valid_p (const mpz_t u, const mpz_t s, const mpz_t r)
{
mpz_t t;
mpz_init (t);
mpz_mul (t, s, s);
mpz_sub (t, u, t);
if (mpz_sgn (t) < 0 || mpz_cmp (t, r) != 0)
{
mpz_clear (t);
return 0;
}
mpz_add_ui (t, s, 1);
mpz_mul (t, t, t);
if (mpz_cmp (t, u) <= 0)
{
mpz_clear (t);
return 0;
}
mpz_clear (t);
return 1;
}
void
mpz_mpn_sqrtrem (mpz_t s, mpz_t r, const mpz_t u)
{
mp_limb_t *sp, *rp;
mp_size_t un, sn, ret;
un = mpz_size (u);
mpz_xor (s, s, u);
sn = (un + 1) / 2;
sp = mpz_limbs_write (s, sn + 1);
sp [sn] = 11;
if (un & 1)
rp = NULL; /* Exploits the fact that r already is correct. */
else {
mpz_add (r, u, s);
rp = mpz_limbs_write (r, un + 1);
rp [un] = 19;
}
ret = mpn_sqrtrem (sp, rp, mpz_limbs_read (u), un);
if (sp [sn] != 11)
{
fprintf (stderr, "mpn_sqrtrem buffer overrun on sp.\n");
abort ();
}
if (un & 1) {
if ((ret != 0) != (mpz_size (r) != 0)) {
fprintf (stderr, "mpn_sqrtrem wrong return value with NULL.\n");
abort ();
}
} else {
mpz_limbs_finish (r, ret);
if ((size_t) ret != mpz_size (r)) {
fprintf (stderr, "mpn_sqrtrem wrong return value.\n");
abort ();
}
if (rp [un] != 19)
{
fprintf (stderr, "mpn_sqrtrem buffer overrun on rp.\n");
abort ();
}
}
mpz_limbs_finish (s, (un + 1) / 2);
}
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t u, s, r;
mpz_init (s);
mpz_init (r);
mpz_init_set_si (u, -1);
if (mpz_perfect_square_p (u))
{
fprintf (stderr, "mpz_perfect_square_p failed on -1.\n");
abort ();
}
if (!mpz_perfect_square_p (s))
{
fprintf (stderr, "mpz_perfect_square_p failed on 0.\n");
abort ();
}
for (i = 0; i < COUNT; i++)
{
mini_rrandomb (u, MAXBITS - (i & 0xFF));
mpz_sqrtrem (s, r, u);
if (!sqrtrem_valid_p (u, s, r))
{
fprintf (stderr, "mpz_sqrtrem failed:\n");
dump ("u", u);
dump ("sqrt", s);
dump ("rem", r);
abort ();
}
mpz_mpn_sqrtrem (s, r, u);
if (!sqrtrem_valid_p (u, s, r))
{
fprintf (stderr, "mpn_sqrtrem failed:\n");
dump ("u", u);
dump ("sqrt", s);
dump ("rem", r);
abort ();
}
if (mpz_sgn (r) == 0) {
mpz_neg (u, u);
mpz_sub_ui (u, u, 1);
}
if ((mpz_sgn (u) <= 0 || (i & 1)) ?
mpz_perfect_square_p (u) :
mpn_perfect_square_p (mpz_limbs_read (u), mpz_size (u)))
{
fprintf (stderr, "mp%s_perfect_square_p failed on non square:\n",
(mpz_sgn (u) <= 0 || (i & 1)) ? "z" : "n");
dump ("u", u);
abort ();
}
mpz_mul (u, s, s);
if (!((mpz_sgn (u) <= 0 || (i & 1)) ?
mpz_perfect_square_p (u) :
mpn_perfect_square_p (mpz_limbs_read (u), mpz_size (u))))
{
fprintf (stderr, "mp%s_perfect_square_p failed on square:\n",
(mpz_sgn (u) <= 0 || (i & 1)) ? "z" : "n");
dump ("u", u);
abort ();
}
}
mpz_clear (u);
mpz_clear (s);
mpz_clear (r);
}

View File

@@ -0,0 +1,332 @@
/*
Copyright 2012-2014, 2016 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 <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 2000
#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
#define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
static void
test_small (void)
{
struct {
const char *input;
const char *decimal;
} data[] = {
{ "183407", "183407" },
{ " 763959", "763959 " },
{ "9 81999", "981999" },
{ "10\t7398 ", "107398" },
{ "-9585 44", "-00958544" },
{ "-0", "0000" },
{ " -000 ", "0" },
{ "0704436", "231710" },
/* Check the case of large number of leading zeros. */
{ "0000000000000000000000000", "0000000000000000000000000" },
{ "000000000000000000000000704436", "000000000000000000000000231710" },
{ " 02503517", "689999" },
{ "0 1312143", "365667" },
{ "-03 274062", "-882738" },
{ "012\t242", "005282" },
{ "0b11010111110010001111", "883855" },
{ " 0b11001010010100001", "103585" },
{ "-0b101010110011101111", "-175343" },
{ "0b 1111111011011100110", "521958" },
{ "0b1 1111110111001000011", "1044035" },
{ " 0x53dfc", "343548" },
{ "0xfA019", "1024025" },
{ "0x 642d1", "410321" },
{ "0x5 8067", "360551" },
{ "-0xd6Be6", "-879590" },
{ "\t0B1110000100000000011", "460803" },
{ "0B\t1111110010010100101", "517285" },
{ "0B1\t010111101101110100", "359284" },
{ "-0B101\t1001101111111001", "-367609" },
{ "0B10001001010111110000", "562672" },
{ "0Xe4B7e", "936830" },
{ "0X1E4bf", "124095" },
{ "-0Xfdb90", "-1039248" },
{ "0X7fc47", "523335" },
{ "0X8167c", "530044" },
/* Some invalid inputs */
{ "", NULL },
{ "0x", NULL },
{ "0b", NULL },
{ "0z", NULL },
{ "-", NULL },
{ "-0x ", NULL },
{ "0|1", NULL },
{ "4+4", NULL },
{ "0ab", NULL },
{ "10x0", NULL },
{ "0xxab", NULL },
{ "ab", NULL },
{ "0%#", NULL },
{ "$foo", NULL },
{ NULL, NULL }
};
unsigned i;
mpz_t a, b;
mpz_init (b);
for (i = 0; data[i].input; i++)
{
int res = mpz_init_set_str (a, data[i].input, 0);
if (data[i].decimal)
{
if (res != 0)
{
fprintf (stderr, "mpz_set_str returned -1, input: %s\n",
data[i].input);
abort ();
}
if (mpz_set_str (b, data[i].decimal, 10) != 0)
{
fprintf (stderr, "mpz_set_str returned -1, decimal input: %s\n",
data[i].input);
abort ();
}
if (mpz_cmp (a, b) != 0)
{
fprintf (stderr, "mpz_set_str failed for input: %s\n",
data[i].input);
dump ("got", a);
dump ("ref", b);
abort ();
}
}
else if (res != -1)
{
fprintf (stderr, "mpz_set_str returned %d, invalid input: %s\n",
res, data[i].input);
abort ();
}
mpz_clear (a);
}
mpz_clear (b);
}
void
testmain (int argc, char **argv)
{
unsigned i;
char *ap;
char *bp;
char *rp;
size_t bn, rn, arn, bps;
mpz_t a, b;
FILE *tmp;
test_small ();
mpz_init (a);
mpz_init (b);
tmp = tmpfile ();
if (!tmp)
fprintf (stderr,
"Failed to create temporary file. Skipping mpz_out_str tests.\n");
if (mpz_out_str (tmp, 63, a) != 0)
{
printf ("mpz_out_str did not return 0 (error) with base > 62\n");
abort ();
}
if (mpz_out_str (tmp, -37, a) != 0)
{
printf ("mpz_out_str did not return 0 (error) with base < -37\n");
abort ();
}
for (i = 0; i < COUNT; i++)
{
int base;
for (base = 0; base <= 62; base += 1 + (base == 0))
{
hex_random_str_op (MAXBITS, (i&1 || base > 36) ? base: -base, &ap, &rp);
if (mpz_set_str (a, ap, 16) != 0)
{
fprintf (stderr, "mpz_set_str failed on input %s\n", ap);
abort ();
}
rn = strlen (rp);
arn = rn - (rp[0] == '-');
bn = mpz_sizeinbase (a, base ? base : 10);
if (bn < arn || bn > (arn + 1))
{
fprintf (stderr, "mpz_sizeinbase failed:\n");
dump ("a", a);
fprintf (stderr, "r = %s\n", rp);
fprintf (stderr, " base %d, correct size %u, got %u\n",
base, (unsigned) arn, (unsigned)bn);
abort ();
}
bp = mpz_get_str (NULL, (i&1 || base > 36) ? base: -base, a);
bps = strlen(bp) + 1;
if (strcmp (bp, rp))
{
fprintf (stderr, "mpz_get_str failed:\n");
dump ("a", a);
fprintf (stderr, "b = %s\n", bp);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", rp);
abort ();
}
/* Just a few tests with file i/o. */
if (tmp && i < 20)
{
size_t tn;
rewind (tmp);
tn = mpz_out_str (tmp, (i&1 || base > 36) ? base: -base, a);
if (tn != rn)
{
fprintf (stderr, "mpz_out_str, bad return value:\n");
dump ("a", a);
fprintf (stderr, "r = %s\n", rp);
fprintf (stderr, " base %d, correct size %u, got %u\n",
base, (unsigned) rn, (unsigned)tn);
abort ();
}
rewind (tmp);
memset (bp, 0, rn);
tn = fread (bp, 1, rn, tmp);
if (tn != rn)
{
fprintf (stderr,
"fread failed, expected %lu bytes, got only %lu.\n",
(unsigned long) rn, (unsigned long) tn);
abort ();
}
if (memcmp (bp, rp, rn) != 0)
{
fprintf (stderr, "mpz_out_str failed:\n");
dump ("a", a);
fprintf (stderr, "b = %s\n", bp);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", rp);
abort ();
}
}
mpz_set_str (b, rp, base);
if (mpz_cmp (a, b))
{
fprintf (stderr, "mpz_set_str failed:\n");
fprintf (stderr, "r = %s\n", rp);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", ap);
fprintf (stderr, " base = 16\n");
dump ("b", b);
dump ("r", a);
abort ();
}
/* Test mpn interface */
if (base && mpz_sgn (a))
{
size_t i;
const char *absr;
mp_limb_t t[MAXLIMBS];
size_t tn = mpz_size (a);
assert (tn <= MAXLIMBS);
mpn_copyi (t, a->_mp_d, tn);
bn = mpn_get_str ((unsigned char *) bp, base, t, tn);
if (bn != arn)
{
fprintf (stderr, "mpn_get_str failed:\n");
fprintf (stderr, "returned length: %lu (bad)\n", (unsigned long) bn);
fprintf (stderr, "expected: %lu\n", (unsigned long) arn);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", ap);
fprintf (stderr, " base = 16\n");
dump ("b", b);
dump ("r", a);
abort ();
}
absr = rp + (rp[0] == '-');
for (i = 0; i < bn; i++)
{
unsigned char digit = absr[i];
char value;
if (digit >= '0' && digit <= '9')
value = digit - '0';
else if (digit >= 'a' && digit <= 'z')
value = digit - 'a' + ((base > 36) ? 36 : 10);
else if (digit >= 'A' && digit <= 'Z')
value = digit - 'A' + 10;
else
{
fprintf (stderr, "Internal error in test.\n");
abort();
}
if (bp[i] != value)
{
fprintf (stderr, "mpn_get_str failed:\n");
fprintf (stderr, "digit %lu: %d (bad)\n", (unsigned long) i, bp[i]);
fprintf (stderr, "expected: %d\n", value);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", ap);
fprintf (stderr, " base = 16\n");
dump ("b", b);
dump ("r", a);
abort ();
}
}
tn = mpn_set_str (t, (unsigned char *) bp, bn, base);
if (tn != mpz_size (a) || mpn_cmp (t, a->_mp_d, tn))
{
fprintf (stderr, "mpn_set_str failed:\n");
fprintf (stderr, "r = %s\n", rp);
fprintf (stderr, " base = %d\n", base);
fprintf (stderr, "r = %s\n", ap);
fprintf (stderr, " base = 16\n");
dump ("r", a);
abort ();
}
}
free (ap);
free (rp);
testfree (bp, bps);
}
}
mpz_clear (a);
mpz_clear (b);
}

View File

@@ -0,0 +1,71 @@
/*
Copyright 2012, 2013 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 <stdlib.h>
#include <stdio.h>
#include "testutils.h"
#define MAXBITS 400
#define COUNT 10000
void
testmain (int argc, char **argv)
{
unsigned i;
mpz_t a, b, res, res_ui, ref;
mpz_init (a);
mpz_init (b);
mpz_init (res);
mpz_init (res_ui);
mpz_init (ref);
for (i = 0; i < COUNT; i++)
{
mini_random_op3 (OP_SUB, MAXBITS, a, b, ref);
mpz_sub (res, a, b);
if (mpz_cmp (res, ref))
{
fprintf (stderr, "mpz_sub failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res);
dump ("ref", ref);
abort ();
}
if (mpz_fits_ulong_p (a)) {
mpz_ui_sub (res_ui, mpz_get_ui (a), b);
if (mpz_cmp (res_ui, ref))
{
fprintf (stderr, "mpz_ui_sub failed:\n");
dump ("a", a);
dump ("b", b);
dump ("r", res_ui);
dump ("ref", ref);
abort ();
}
}
}
mpz_clear (a);
mpz_clear (b);
mpz_clear (res);
mpz_clear (res_ui);
mpz_clear (ref);
}

View File

@@ -0,0 +1,196 @@
/*
Copyright 2013-2015, 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 "testutils.h"
/* Include it here, so we we could tweak, e.g., how MPZ_REALLOC
works. */
#include "../mini-gmp.c"
#include "../mini-mpq.c"
static size_t total_alloc = 0;
/* Custom memory allocation to track memory usage, and add a small red
zone.
About alignment: In general, getting a block from malloc, and
incrementing it by sizeof(size_t), like we do here, might give a
pointer which is not properly aligned for all types. But the
largest type we allocate space for is unsigned long (mp_limb_t),
which shouldn't have stricter alignment requirements than
size_t. */
static unsigned char block_end[8] =
{ 0x7c, 0x37, 0xd6, 0x12, 0xa8, 0x6c, 0x01, 0xd1 };
static void *
block_init (size_t *block, size_t size)
{
char *p;
*block++ = size;
p = (char *) block;
memcpy (p + size, block_end, sizeof(block_end));
total_alloc += size;
return p;
}
/* Check small redzone, return pointer to malloced block. */
static size_t *
block_check (void *p)
{
size_t *block = (size_t *) p - 1;
size_t size = block[0];
if (memcmp ((char *)p + size, block_end, sizeof(block_end)) != 0)
{
fprintf (stderr, "red zone overwritten.\n");
abort ();
}
total_alloc -= size;
return block;
}
static void *
tu_alloc (size_t size)
{
size_t *block = (size_t *) malloc (sizeof(size_t) + size + sizeof(block_end));
if (!block)
{
fprintf (stderr, "Virtual memory exhausted.\n");
abort ();
}
return block_init (block, size);
}
static void *
tu_realloc (void *p, size_t old_size, size_t new_size)
{
size_t *block;
size_t *old_block = block_check (p);
if (old_block[0] != old_size)
{
fprintf (stderr, "%s:%d: bad old_size: want %ld, got %ld.\n", __FILE__, __LINE__,
(long)old_block[0], (long)old_size);
abort ();
}
block = (size_t *) realloc (old_block, sizeof(size_t) + new_size + sizeof(block_end));
if (!block)
{
fprintf (stderr, "Virtual memory exhausted.\n");
abort ();
}
return block_init (block, new_size);
}
static void
tu_free (void *p, size_t old_size)
{
size_t *old_block = block_check (p);
if (old_block[0] != old_size && old_size != 0)
{
fprintf (stderr, "%s:%d: bad old_size: want %ld, got %ld.\n", __FILE__, __LINE__,
(long)old_block[0], (long)old_size);
abort ();
}
free (old_block);
}
/* Free memory allocated via mini-gmp allocation function. */
void
testfree (void *p, size_t size)
{
void (*freefunc) (void *, size_t);
mp_get_memory_functions (NULL, NULL, &freefunc);
freefunc (p, size);
}
int
main (int argc, char **argv)
{
hex_random_init ();
mp_set_memory_functions (tu_alloc, tu_realloc, tu_free);
/* Currently, t-comb seems to be the only program accepting any
arguments. It might make sense to parse common arguments here. */
testmain (argc, argv);
if (total_alloc != 0)
{
fprintf (stderr, "Memory leaked: %lu bytes.\n",
(unsigned long) total_alloc);
abort ();
}
return 0;
}
void
testhalves (int count, void (*tested_fun) (int))
{
void (*freefunc) (void *, size_t);
void *(*reallocfunc) (void *, size_t, size_t);
void *(*allocfunc) (size_t);
size_t initial_alloc;
mp_get_memory_functions (&allocfunc, &reallocfunc, &freefunc);
initial_alloc = total_alloc;
(*tested_fun) (count / 2);
if (initial_alloc != total_alloc)
{
fprintf (stderr, "First half, memory leaked: %lu bytes.\n",
(unsigned long) total_alloc - initial_alloc);
abort ();
}
mp_set_memory_functions (NULL, NULL, NULL);
(*tested_fun) (count / 2);
mp_set_memory_functions (allocfunc, reallocfunc, freefunc);
}
void
dump (const char *label, const mpz_t x)
{
char *buf = mpz_get_str (NULL, 16, x);
fprintf (stderr, "%s: %s\n", label, buf);
testfree (buf, strlen(buf) + 1);
}
void
mpz_set_str_or_abort (mpz_ptr z, const char *str, int base)
{
if (mpz_set_str (z, str, base) != 0)
{
fprintf (stderr, "ERROR: mpz_set_str failed\n");
fprintf (stderr, " str = \"%s\"\n", str);
fprintf (stderr, " base = %d\n", base);
abort();
}
}
int
mpz_lucas_mod (mpz_t V, mpz_t Qk, long Q,
mp_bitcnt_t b0, const mpz_t n)
{
return gmp_lucas_mod (V, Qk, Q, b0, n);
}

View File

@@ -0,0 +1,42 @@
/*
Copyright 2013, 2014, 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 "mini-random.h"
#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
void testmain (int argc, char **argv);
void testhalves (int count, void (*tested_fun) (int));
void testfree (void *p, size_t size);
void
dump (const char *label, const mpz_t x);
void
mpz_set_str_or_abort (mpz_ptr z, const char *str, int base);
/* Prototype for wrappers to internal functions to be tested. */
int
mpz_lucas_mod (mpz_t V, mpz_t Qk, long Q,
mp_bitcnt_t b0, const mpz_t n);