Home | History | Annotate | Line # | Download | only in mpz
      1  1.1  mrg /* Test mpz_limbs_* functions
      2  1.1  mrg 
      3  1.1  mrg Copyright 2013 Free Software Foundation, Inc.
      4  1.1  mrg 
      5  1.1  mrg This file is part of the GNU MP Library test suite.
      6  1.1  mrg 
      7  1.1  mrg The GNU MP Library test suite is free software; you can redistribute it
      8  1.1  mrg and/or modify it under the terms of the GNU General Public License as
      9  1.1  mrg published by the Free Software Foundation; either version 3 of the License,
     10  1.1  mrg or (at your option) any later version.
     11  1.1  mrg 
     12  1.1  mrg The GNU MP Library test suite is distributed in the hope that it will be
     13  1.1  mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15  1.1  mrg Public License for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License along with
     18  1.1  mrg the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     19  1.1  mrg 
     20  1.1  mrg #include <stdlib.h>
     21  1.1  mrg #include <stdio.h>
     22  1.1  mrg 
     23  1.1  mrg #include "gmp-impl.h"
     24  1.1  mrg #include "tests.h"
     25  1.1  mrg 
     26  1.1  mrg #define COUNT 100
     27  1.1  mrg #define BITSIZE 500
     28  1.1  mrg 
     29  1.1  mrg /* Like mpz_add. For simplicity, support positive inputs only. */
     30  1.1  mrg static void
     31  1.1  mrg alt_add (mpz_ptr r, mpz_srcptr a, mpz_srcptr b)
     32  1.1  mrg {
     33  1.1  mrg   mp_size_t an = mpz_size (a);
     34  1.1  mrg   mp_size_t bn = mpz_size (b);
     35  1.1  mrg   mp_ptr rp;
     36  1.1  mrg 
     37  1.1  mrg   ASSERT (an > 0);
     38  1.1  mrg   ASSERT (bn > 0);
     39  1.1  mrg   if (an < bn)
     40  1.1  mrg     {
     41  1.1  mrg       MP_SIZE_T_SWAP (an, bn);
     42  1.1  mrg       MPZ_SRCPTR_SWAP (a, b);
     43  1.1  mrg     }
     44  1.1  mrg   rp = mpz_limbs_modify (r, an + 1);
     45  1.1  mrg   rp[an] = mpn_add (rp, mpz_limbs_read (a), an, mpz_limbs_read (b), bn);
     46  1.1  mrg   mpz_limbs_finish (r, an + 1);
     47  1.1  mrg }
     48  1.1  mrg 
     49  1.1  mrg static void
     50  1.1  mrg check_funcs (const char *name,
     51  1.1  mrg 	     void (*f)(mpz_ptr, mpz_srcptr, mpz_srcptr),
     52  1.1  mrg 	     void (*ref_f)(mpz_ptr, mpz_srcptr, mpz_srcptr),
     53  1.1  mrg 	     mpz_srcptr a, mpz_srcptr b)
     54  1.1  mrg {
     55  1.1  mrg   mpz_t r, ref;
     56  1.1  mrg   mpz_inits (r, ref, NULL);
     57  1.1  mrg 
     58  1.1  mrg   ref_f (ref, a, b);
     59  1.1  mrg   MPZ_CHECK_FORMAT (ref);
     60  1.1  mrg   f (r, a, b);
     61  1.1  mrg   MPZ_CHECK_FORMAT (r);
     62  1.1  mrg 
     63  1.1  mrg   if (mpz_cmp (r, ref) != 0)
     64  1.1  mrg     {
     65  1.1  mrg       printf ("%s failed, abits %u, bbits %u\n",
     66  1.1  mrg 	      name,
     67  1.1  mrg 	      (unsigned) mpz_sizeinbase (a, 2),
     68  1.1  mrg 	      (unsigned) mpz_sizeinbase (b, 2));
     69  1.1  mrg       gmp_printf ("a = %Zx\n", a);
     70  1.1  mrg       gmp_printf ("b = %Zx\n", b);
     71  1.1  mrg       gmp_printf ("r = %Zx (bad)\n", r);
     72  1.1  mrg       gmp_printf ("ref = %Zx\n", ref);
     73  1.1  mrg       abort ();
     74  1.1  mrg     }
     75  1.1  mrg   mpz_clears (r, ref, NULL);
     76  1.1  mrg }
     77  1.1  mrg 
     78  1.1  mrg static void
     79  1.1  mrg check_add (void)
     80  1.1  mrg {
     81  1.1  mrg   gmp_randstate_ptr rands = RANDS;
     82  1.1  mrg   mpz_t bs, a, b;
     83  1.1  mrg   unsigned i;
     84  1.1  mrg   mpz_inits (bs, a, b, NULL);
     85  1.1  mrg   for (i = 0; i < COUNT; i++)
     86  1.1  mrg     {
     87  1.1  mrg       mpz_urandomb (bs, rands, 32);
     88  1.1  mrg       mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE);
     89  1.1  mrg       mpz_urandomb (bs, rands, 32);
     90  1.1  mrg       mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE);
     91  1.1  mrg 
     92  1.1  mrg       check_funcs ("add", alt_add, mpz_add, a, b);
     93  1.1  mrg     }
     94  1.1  mrg   mpz_clears (bs, a, b, NULL);
     95  1.1  mrg }
     96  1.1  mrg 
     97  1.1  mrg static void
     98  1.1  mrg alt_mul (mpz_ptr r, mpz_srcptr a, mpz_srcptr b)
     99  1.1  mrg {
    100  1.1  mrg   mp_size_t an = mpz_size (a);
    101  1.1  mrg   mp_size_t bn = mpz_size (b);
    102  1.1  mrg   mp_srcptr ap, bp;
    103  1.1  mrg   TMP_DECL;
    104  1.1  mrg 
    105  1.1  mrg   TMP_MARK;
    106  1.1  mrg 
    107  1.1  mrg   ASSERT (an > 0);
    108  1.1  mrg   ASSERT (bn > 0);
    109  1.1  mrg   if (an < bn)
    110  1.1  mrg     {
    111  1.1  mrg       MP_SIZE_T_SWAP (an, bn);
    112  1.1  mrg       MPZ_SRCPTR_SWAP (a, b);
    113  1.1  mrg     }
    114  1.1  mrg   /* NOTE: This copying seems unnecessary; better to allocate new
    115  1.1  mrg      result area, and free the old area when done. */
    116  1.1  mrg   if (r == a)
    117  1.1  mrg     {
    118  1.1  mrg       mp_ptr tp =  TMP_ALLOC_LIMBS (an);
    119  1.1  mrg       MPN_COPY (tp, mpz_limbs_read (a), an);
    120  1.1  mrg       ap = tp;
    121  1.1  mrg       bp = (a == b) ? ap : mpz_limbs_read (b);
    122  1.1  mrg     }
    123  1.1  mrg   else if (r == b)
    124  1.1  mrg     {
    125  1.1  mrg       mp_ptr tp = TMP_ALLOC_LIMBS (bn);
    126  1.1  mrg       MPN_COPY (tp, mpz_limbs_read (b), bn);
    127  1.1  mrg       bp = tp;
    128  1.1  mrg       ap = mpz_limbs_read (a);
    129  1.1  mrg     }
    130  1.1  mrg   else
    131  1.1  mrg     {
    132  1.1  mrg       ap = mpz_limbs_read (a);
    133  1.1  mrg       bp = mpz_limbs_read (b);
    134  1.1  mrg     }
    135  1.1  mrg   mpn_mul (mpz_limbs_write (r, an + bn),
    136  1.1  mrg 	   ap, an, bp, bn);
    137  1.1  mrg 
    138  1.1  mrg   mpz_limbs_finish (r, an + bn);
    139  1.1  mrg }
    140  1.1  mrg 
    141  1.1  mrg void
    142  1.1  mrg check_mul (void)
    143  1.1  mrg {
    144  1.1  mrg   gmp_randstate_ptr rands = RANDS;
    145  1.1  mrg   mpz_t bs, a, b;
    146  1.1  mrg   unsigned i;
    147  1.1  mrg   mpz_inits (bs, a, b, NULL);
    148  1.1  mrg   for (i = 0; i < COUNT; i++)
    149  1.1  mrg     {
    150  1.1  mrg       mpz_urandomb (bs, rands, 32);
    151  1.1  mrg       mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE);
    152  1.1  mrg       mpz_urandomb (bs, rands, 32);
    153  1.1  mrg       mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE);
    154  1.1  mrg 
    155  1.1  mrg       check_funcs ("mul", alt_mul, mpz_mul, a, b);
    156  1.1  mrg     }
    157  1.1  mrg   mpz_clears (bs, a, b, NULL);
    158  1.1  mrg }
    159  1.1  mrg 
    160  1.1  mrg #define MAX_SIZE 100
    161  1.1  mrg 
    162  1.1  mrg static void
    163  1.1  mrg check_roinit (void)
    164  1.1  mrg {
    165  1.1  mrg   gmp_randstate_ptr rands = RANDS;
    166  1.1  mrg   mpz_t bs, a, b, r, ref;
    167  1.1  mrg   unsigned i;
    168  1.1  mrg 
    169  1.1  mrg   mpz_inits (bs, a, b, r, ref, NULL);
    170  1.1  mrg 
    171  1.1  mrg   for (i = 0; i < COUNT; i++)
    172  1.1  mrg     {
    173  1.1  mrg       mp_srcptr ap, bp;
    174  1.1  mrg       mp_size_t an, bn;
    175  1.1  mrg       mpz_urandomb (bs, rands, 32);
    176  1.1  mrg       mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE);
    177  1.1  mrg       mpz_urandomb (bs, rands, 32);
    178  1.1  mrg       mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE);
    179  1.1  mrg 
    180  1.1  mrg       an = mpz_size (a);
    181  1.1  mrg       ap = mpz_limbs_read (a);
    182  1.1  mrg       bn = mpz_size (b);
    183  1.1  mrg       bp = mpz_limbs_read (b);
    184  1.1  mrg 
    185  1.1  mrg       mpz_add (ref, a, b);
    186  1.1  mrg       {
    187  1.1  mrg 	mpz_t a1, b1;
    188  1.1  mrg #if __STDC_VERSION__ >= 199901
    189  1.1  mrg 	const mpz_t a2 = MPZ_ROINIT_N ( (mp_ptr) ap, an);
    190  1.1  mrg 	const mpz_t b2 = MPZ_ROINIT_N ( (mp_ptr) bp, bn);
    191  1.1  mrg 
    192  1.1  mrg 	mpz_set_ui (r, 0);
    193  1.1  mrg 	mpz_add (r, a2, b2);
    194  1.1  mrg 	if (mpz_cmp (r, ref) != 0)
    195  1.1  mrg 	  {
    196  1.1  mrg 	    printf ("MPZ_ROINIT_N failed\n");
    197  1.1  mrg 	    gmp_printf ("a = %Zx\n", a);
    198  1.1  mrg 	    gmp_printf ("b = %Zx\n", b);
    199  1.1  mrg 	    gmp_printf ("r = %Zx (bad)\n", r);
    200  1.1  mrg 	    gmp_printf ("ref = %Zx\n", ref);
    201  1.1  mrg 	    abort ();
    202  1.1  mrg 	  }
    203  1.1  mrg #endif
    204  1.1  mrg 	mpz_set_ui (r, 0);
    205  1.1  mrg 	mpz_add (r, mpz_roinit_n (a1, ap, an), mpz_roinit_n (b1, bp, bn));
    206  1.1  mrg 	if (mpz_cmp (r, ref) != 0)
    207  1.1  mrg 	  {
    208  1.1  mrg 	    printf ("mpz_roinit_n failed\n");
    209  1.1  mrg 	    gmp_printf ("a = %Zx\n", a);
    210  1.1  mrg 	    gmp_printf ("b = %Zx\n", b);
    211  1.1  mrg 	    gmp_printf ("r = %Zx (bad)\n", r);
    212  1.1  mrg 	    gmp_printf ("ref = %Zx\n", ref);
    213  1.1  mrg 	    abort ();
    214  1.1  mrg 	  }
    215  1.1  mrg       }
    216  1.1  mrg     }
    217  1.1  mrg   mpz_clears (bs, a, b, r, ref, NULL);
    218  1.1  mrg }
    219  1.1  mrg 
    220  1.1  mrg int
    221  1.1  mrg main (int argc, char *argv[])
    222  1.1  mrg {
    223  1.1  mrg   tests_start ();
    224  1.1  mrg   tests_end ();
    225  1.1  mrg 
    226  1.1  mrg   check_add ();
    227  1.1  mrg   check_mul ();
    228  1.1  mrg   check_roinit ();
    229  1.1  mrg 
    230  1.1  mrg   return 0;
    231  1.1  mrg 
    232  1.1  mrg }
    233