From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- gmp-6.3.0/tests/mpz/t-limbs.c | 232 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 gmp-6.3.0/tests/mpz/t-limbs.c (limited to 'gmp-6.3.0/tests/mpz/t-limbs.c') diff --git a/gmp-6.3.0/tests/mpz/t-limbs.c b/gmp-6.3.0/tests/mpz/t-limbs.c new file mode 100644 index 0000000..6526e92 --- /dev/null +++ b/gmp-6.3.0/tests/mpz/t-limbs.c @@ -0,0 +1,232 @@ +/* Test mpz_limbs_* functions + +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 +#include + +#include "gmp-impl.h" +#include "tests.h" + +#define COUNT 100 +#define BITSIZE 500 + +/* Like mpz_add. For simplicity, support positive inputs only. */ +static void +alt_add (mpz_ptr r, mpz_srcptr a, mpz_srcptr b) +{ + mp_size_t an = mpz_size (a); + mp_size_t bn = mpz_size (b); + mp_ptr rp; + + ASSERT (an > 0); + ASSERT (bn > 0); + if (an < bn) + { + MP_SIZE_T_SWAP (an, bn); + MPZ_SRCPTR_SWAP (a, b); + } + rp = mpz_limbs_modify (r, an + 1); + rp[an] = mpn_add (rp, mpz_limbs_read (a), an, mpz_limbs_read (b), bn); + mpz_limbs_finish (r, an + 1); +} + +static void +check_funcs (const char *name, + void (*f)(mpz_ptr, mpz_srcptr, mpz_srcptr), + void (*ref_f)(mpz_ptr, mpz_srcptr, mpz_srcptr), + mpz_srcptr a, mpz_srcptr b) +{ + mpz_t r, ref; + mpz_inits (r, ref, NULL); + + ref_f (ref, a, b); + MPZ_CHECK_FORMAT (ref); + f (r, a, b); + MPZ_CHECK_FORMAT (r); + + if (mpz_cmp (r, ref) != 0) + { + printf ("%s failed, abits %u, bbits %u\n", + name, + (unsigned) mpz_sizeinbase (a, 2), + (unsigned) mpz_sizeinbase (b, 2)); + gmp_printf ("a = %Zx\n", a); + gmp_printf ("b = %Zx\n", b); + gmp_printf ("r = %Zx (bad)\n", r); + gmp_printf ("ref = %Zx\n", ref); + abort (); + } + mpz_clears (r, ref, NULL); +} + +static void +check_add (void) +{ + gmp_randstate_ptr rands = RANDS; + mpz_t bs, a, b; + unsigned i; + mpz_inits (bs, a, b, NULL); + for (i = 0; i < COUNT; i++) + { + mpz_urandomb (bs, rands, 32); + mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); + mpz_urandomb (bs, rands, 32); + mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); + + check_funcs ("add", alt_add, mpz_add, a, b); + } + mpz_clears (bs, a, b, NULL); +} + +static void +alt_mul (mpz_ptr r, mpz_srcptr a, mpz_srcptr b) +{ + mp_size_t an = mpz_size (a); + mp_size_t bn = mpz_size (b); + mp_srcptr ap, bp; + TMP_DECL; + + TMP_MARK; + + ASSERT (an > 0); + ASSERT (bn > 0); + if (an < bn) + { + MP_SIZE_T_SWAP (an, bn); + MPZ_SRCPTR_SWAP (a, b); + } + /* NOTE: This copying seems unnecessary; better to allocate new + result area, and free the old area when done. */ + if (r == a) + { + mp_ptr tp = TMP_ALLOC_LIMBS (an); + MPN_COPY (tp, mpz_limbs_read (a), an); + ap = tp; + bp = (a == b) ? ap : mpz_limbs_read (b); + } + else if (r == b) + { + mp_ptr tp = TMP_ALLOC_LIMBS (bn); + MPN_COPY (tp, mpz_limbs_read (b), bn); + bp = tp; + ap = mpz_limbs_read (a); + } + else + { + ap = mpz_limbs_read (a); + bp = mpz_limbs_read (b); + } + mpn_mul (mpz_limbs_write (r, an + bn), + ap, an, bp, bn); + + mpz_limbs_finish (r, an + bn); +} + +void +check_mul (void) +{ + gmp_randstate_ptr rands = RANDS; + mpz_t bs, a, b; + unsigned i; + mpz_inits (bs, a, b, NULL); + for (i = 0; i < COUNT; i++) + { + mpz_urandomb (bs, rands, 32); + mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); + mpz_urandomb (bs, rands, 32); + mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); + + check_funcs ("mul", alt_mul, mpz_mul, a, b); + } + mpz_clears (bs, a, b, NULL); +} + +#define MAX_SIZE 100 + +static void +check_roinit (void) +{ + gmp_randstate_ptr rands = RANDS; + mpz_t bs, a, b, r, ref; + unsigned i; + + mpz_inits (bs, a, b, r, ref, NULL); + + for (i = 0; i < COUNT; i++) + { + mp_srcptr ap, bp; + mp_size_t an, bn; + mpz_urandomb (bs, rands, 32); + mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); + mpz_urandomb (bs, rands, 32); + mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); + + an = mpz_size (a); + ap = mpz_limbs_read (a); + bn = mpz_size (b); + bp = mpz_limbs_read (b); + + mpz_add (ref, a, b); + { + mpz_t a1, b1; +#if __STDC_VERSION__ >= 199901 + const mpz_t a2 = MPZ_ROINIT_N ( (mp_ptr) ap, an); + const mpz_t b2 = MPZ_ROINIT_N ( (mp_ptr) bp, bn); + + mpz_set_ui (r, 0); + mpz_add (r, a2, b2); + if (mpz_cmp (r, ref) != 0) + { + printf ("MPZ_ROINIT_N failed\n"); + gmp_printf ("a = %Zx\n", a); + gmp_printf ("b = %Zx\n", b); + gmp_printf ("r = %Zx (bad)\n", r); + gmp_printf ("ref = %Zx\n", ref); + abort (); + } +#endif + mpz_set_ui (r, 0); + mpz_add (r, mpz_roinit_n (a1, ap, an), mpz_roinit_n (b1, bp, bn)); + if (mpz_cmp (r, ref) != 0) + { + printf ("mpz_roinit_n failed\n"); + gmp_printf ("a = %Zx\n", a); + gmp_printf ("b = %Zx\n", b); + gmp_printf ("r = %Zx (bad)\n", r); + gmp_printf ("ref = %Zx\n", ref); + abort (); + } + } + } + mpz_clears (bs, a, b, r, ref, NULL); +} + +int +main (int argc, char *argv[]) +{ + tests_start (); + tests_end (); + + check_add (); + check_mul (); + check_roinit (); + + return 0; + +} -- cgit v1.2.3