github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-limbs.c (about)

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