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

     1  /* Test for mullo function.
     2  
     3  Copyright 2009 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  
    21  #include <stdlib.h>
    22  #include <stdio.h>
    23  
    24  #include "gmp.h"
    25  #include "gmp-impl.h"
    26  #include "tests.h"
    27  
    28  /* Sizes are up to 2^SIZE_LOG limbs */
    29  #ifndef SIZE_LOG
    30  #define SIZE_LOG 10
    31  #endif
    32  
    33  #ifndef COUNT
    34  #define COUNT 10000
    35  #endif
    36  
    37  #define MAX_N (1L << SIZE_LOG)
    38  #define MIN_N (1)
    39  
    40  int
    41  main (int argc, char **argv)
    42  {
    43    mp_ptr ap, bp, refp, pp, scratch;
    44    int count = COUNT;
    45    int test;
    46    gmp_randstate_ptr rands;
    47    TMP_DECL;
    48    TMP_MARK;
    49  
    50    if (argc > 1)
    51      {
    52        char *end;
    53        count = strtol (argv[1], &end, 0);
    54        if (*end || count <= 0)
    55  	{
    56  	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
    57  	  return 1;
    58  	}
    59      }
    60  
    61    tests_start ();
    62    rands = RANDS;
    63  
    64  #define mpn_mullo_itch(n) (0)
    65  
    66    ap = TMP_ALLOC_LIMBS (MAX_N);
    67    bp = TMP_ALLOC_LIMBS (MAX_N);
    68    refp = TMP_ALLOC_LIMBS (MAX_N * 2);
    69    pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
    70    scratch
    71      = 1+TMP_ALLOC_LIMBS (mpn_mullo_itch (MAX_N) + 2);
    72  
    73    for (test = 0; test < count; test++)
    74      {
    75        unsigned size_min;
    76        unsigned size_range;
    77        mp_size_t n;
    78        mp_size_t itch;
    79        mp_limb_t p_before, p_after, s_before, s_after;
    80  
    81        for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
    82  	;
    83  
    84        /* We generate an in the MIN_N <= n <= (1 << size_range). */
    85        size_range = size_min
    86  	+ gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
    87  
    88        n = MIN_N
    89  	+ gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);
    90  
    91        mpn_random2 (ap, n);
    92        mpn_random2 (bp, n);
    93        mpn_random2 (pp-1, n + 2);
    94        p_before = pp[-1];
    95        p_after = pp[n];
    96  
    97        itch = mpn_mullo_itch (n);
    98        ASSERT_ALWAYS (itch <= mpn_mullo_itch (MAX_N));
    99        mpn_random2 (scratch-1, itch+2);
   100        s_before = scratch[-1];
   101        s_after = scratch[itch];
   102  
   103        mpn_mullo_n (pp, ap, bp, n);
   104        mpn_mul_n (refp, ap, bp, n);
   105        if (pp[-1] != p_before || pp[n] != p_after
   106  	  || scratch[-1] != s_before || scratch[itch] != s_after
   107  	  || mpn_cmp (refp, pp, n) != 0)
   108  	{
   109  	  printf ("ERROR in test %d, n = %d",
   110  		  test, (int) n);
   111  	  if (pp[-1] != p_before)
   112  	    {
   113  	      printf ("before pp:"); mpn_dump (pp -1, 1);
   114  	      printf ("keep:   "); mpn_dump (&p_before, 1);
   115  	    }
   116  	  if (pp[n] != p_after)
   117  	    {
   118  	      printf ("after pp:"); mpn_dump (pp + n, 1);
   119  	      printf ("keep:   "); mpn_dump (&p_after, 1);
   120  	    }
   121  	  if (scratch[-1] != s_before)
   122  	    {
   123  	      printf ("before scratch:"); mpn_dump (scratch-1, 1);
   124  	      printf ("keep:   "); mpn_dump (&s_before, 1);
   125  	    }
   126  	  if (scratch[itch] != s_after)
   127  	    {
   128  	      printf ("after scratch:"); mpn_dump (scratch + itch, 1);
   129  	      printf ("keep:   "); mpn_dump (&s_after, 1);
   130  	    }
   131  	  mpn_dump (ap, n);
   132  	  mpn_dump (bp, n);
   133  	  mpn_dump (pp, n);
   134  	  mpn_dump (refp, n);
   135  
   136  	  abort();
   137  	}
   138      }
   139    TMP_FREE;
   140    tests_end ();
   141    return 0;
   142  }