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

     1  /* Test mpz_addmul, mpz_addmul_ui, mpz_submul, mpz_submul_ui.
     2  
     3  Copyright 2001, 2002 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 <stdio.h>
    22  #include <stdlib.h>
    23  #include <string.h>
    24  
    25  #include "gmp.h"
    26  #include "gmp-impl.h"
    27  #include "tests.h"
    28  
    29  
    30  #define M GMP_NUMB_MAX
    31  
    32  
    33  void
    34  check_one_inplace (mpz_srcptr w, mpz_srcptr y)
    35  {
    36    mpz_t  want, got;
    37  
    38    mpz_init (want);
    39    mpz_init (got);
    40  
    41    mpz_mul (want, w, y);
    42    mpz_add (want, w, want);
    43    mpz_set (got, w);
    44    mpz_addmul (got, got, y);
    45    MPZ_CHECK_FORMAT (got);
    46    if (mpz_cmp (want, got) != 0)
    47      {
    48        printf ("mpz_addmul inplace fail\n");
    49      fail:
    50        mpz_trace ("w", w);
    51        mpz_trace ("y", y);
    52        mpz_trace ("want", want);
    53        mpz_trace ("got ", got);
    54        abort ();
    55      }
    56  
    57    mpz_mul (want, w, y);
    58    mpz_sub (want, w, want);
    59    mpz_set (got, w);
    60    mpz_submul (got, got, y);
    61    MPZ_CHECK_FORMAT (got);
    62    if (mpz_cmp (want, got) != 0)
    63      {
    64        printf ("mpz_submul inplace fail\n");
    65        goto fail;
    66      }
    67  
    68    mpz_clear (want);
    69    mpz_clear (got);
    70  }
    71  
    72  void
    73  check_one_ui_inplace (mpz_ptr w, unsigned long y)
    74  {
    75    mpz_t  want, got;
    76  
    77    mpz_init (want);
    78    mpz_init (got);
    79  
    80    mpz_mul_ui (want, w, (unsigned long) y);
    81    mpz_add (want, w, want);
    82    mpz_set (got, w);
    83    mpz_addmul_ui (got, got, (unsigned long) y);
    84    MPZ_CHECK_FORMAT (got);
    85    if (mpz_cmp (want, got) != 0)
    86      {
    87        printf ("mpz_addmul_ui fail\n");
    88      fail:
    89        mpz_trace ("w", w);
    90        printf    ("y=0x%lX   %lu\n", y, y);
    91        mpz_trace ("want", want);
    92        mpz_trace ("got ", got);
    93        abort ();
    94      }
    95  
    96    mpz_mul_ui (want, w, y);
    97    mpz_sub (want, w, want);
    98    mpz_set (got, w);
    99    mpz_submul_ui (got, got, y);
   100    MPZ_CHECK_FORMAT (got);
   101    if (mpz_cmp (want, got) != 0)
   102      {
   103        printf ("mpz_submul_ui fail\n");
   104        goto fail;
   105      }
   106  
   107    mpz_clear (want);
   108    mpz_clear (got);
   109  }
   110  
   111  void
   112  check_all_inplace (mpz_ptr w, mpz_ptr y)
   113  {
   114    int  wneg, yneg;
   115  
   116    MPZ_CHECK_FORMAT (w);
   117    MPZ_CHECK_FORMAT (y);
   118  
   119    for (wneg = 0; wneg < 2; wneg++)
   120      {
   121        for (yneg = 0; yneg < 2; yneg++)
   122          {
   123            check_one_inplace (w, y);
   124  
   125            if (mpz_fits_ulong_p (y))
   126              check_one_ui_inplace (w, mpz_get_ui (y));
   127  
   128            mpz_neg (y, y);
   129          }
   130        mpz_neg (w, w);
   131      }
   132  }
   133  
   134  void
   135  check_one (mpz_srcptr w, mpz_srcptr x, mpz_srcptr y)
   136  {
   137    mpz_t  want, got;
   138  
   139    mpz_init (want);
   140    mpz_init (got);
   141  
   142    mpz_mul (want, x, y);
   143    mpz_add (want, w, want);
   144    mpz_set (got, w);
   145    mpz_addmul (got, x, y);
   146    MPZ_CHECK_FORMAT (got);
   147    if (mpz_cmp (want, got) != 0)
   148      {
   149        printf ("mpz_addmul fail\n");
   150      fail:
   151        mpz_trace ("w", w);
   152        mpz_trace ("x", x);
   153        mpz_trace ("y", y);
   154        mpz_trace ("want", want);
   155        mpz_trace ("got ", got);
   156        abort ();
   157      }
   158  
   159    mpz_mul (want, x, y);
   160    mpz_sub (want, w, want);
   161    mpz_set (got, w);
   162    mpz_submul (got, x, y);
   163    MPZ_CHECK_FORMAT (got);
   164    if (mpz_cmp (want, got) != 0)
   165      {
   166        printf ("mpz_submul fail\n");
   167        goto fail;
   168      }
   169  
   170    mpz_clear (want);
   171    mpz_clear (got);
   172  }
   173  
   174  void
   175  check_one_ui (mpz_ptr w, mpz_ptr x, unsigned long y)
   176  {
   177    mpz_t  want, got;
   178  
   179    mpz_init (want);
   180    mpz_init (got);
   181  
   182    mpz_mul_ui (want, x, (unsigned long) y);
   183    mpz_add (want, w, want);
   184    mpz_set (got, w);
   185    mpz_addmul_ui (got, x, (unsigned long) y);
   186    MPZ_CHECK_FORMAT (got);
   187    if (mpz_cmp (want, got) != 0)
   188      {
   189        printf ("mpz_addmul_ui fail\n");
   190      fail:
   191        mpz_trace ("w", w);
   192        mpz_trace ("x", x);
   193        printf    ("y=0x%lX   %lu\n", y, y);
   194        mpz_trace ("want", want);
   195        mpz_trace ("got ", got);
   196        abort ();
   197      }
   198  
   199    mpz_mul_ui (want, x, y);
   200    mpz_sub (want, w, want);
   201    mpz_set (got, w);
   202    mpz_submul_ui (got, x, y);
   203    MPZ_CHECK_FORMAT (got);
   204    if (mpz_cmp (want, got) != 0)
   205      {
   206        printf ("mpz_submul_ui fail\n");
   207        goto fail;
   208      }
   209  
   210    mpz_clear (want);
   211    mpz_clear (got);
   212  }
   213  
   214  
   215  void
   216  check_all (mpz_ptr w, mpz_ptr x, mpz_ptr y)
   217  {
   218    int    swap, wneg, xneg, yneg;
   219  
   220    MPZ_CHECK_FORMAT (w);
   221    MPZ_CHECK_FORMAT (x);
   222    MPZ_CHECK_FORMAT (y);
   223  
   224    for (swap = 0; swap < 2; swap++)
   225      {
   226        for (wneg = 0; wneg < 2; wneg++)
   227          {
   228            for (xneg = 0; xneg < 2; xneg++)
   229              {
   230                for (yneg = 0; yneg < 2; yneg++)
   231                  {
   232                    check_one (w, x, y);
   233  
   234                    if (mpz_fits_ulong_p (y))
   235                      check_one_ui (w, x, mpz_get_ui (y));
   236  
   237                    mpz_neg (y, y);
   238                  }
   239                mpz_neg (x, x);
   240              }
   241            mpz_neg (w, w);
   242          }
   243        mpz_swap (x, y);
   244      }
   245  }
   246  
   247  void
   248  check_data_inplace_ui (void)
   249  {
   250    static const struct {
   251      mp_limb_t      w[6];
   252      unsigned long  y;
   253  
   254    } data[] = {
   255  
   256      { { 0 }, 0 },
   257      { { 0 }, 1 },
   258      { { 1 }, 1 },
   259      { { 2 }, 1 },
   260  
   261      { { 123 }, 1 },
   262      { { 123 }, ULONG_MAX },
   263      { { M }, 1 },
   264      { { M }, ULONG_MAX },
   265  
   266      { { 123, 456 }, 1 },
   267      { { M, M }, 1 },
   268      { { 123, 456 }, ULONG_MAX },
   269      { { M, M }, ULONG_MAX },
   270  
   271      { { 123, 456, 789 }, 1 },
   272      { { M, M, M }, 1 },
   273      { { 123, 456, 789 }, ULONG_MAX },
   274      { { M, M, M }, ULONG_MAX },
   275    };
   276  
   277    mpz_t  w, y;
   278    int    i;
   279  
   280    mpz_init (w);
   281    mpz_init (y);
   282  
   283    for (i = 0; i < numberof (data); i++)
   284      {
   285        mpz_set_n (w, data[i].w, (mp_size_t) numberof(data[i].w));
   286        mpz_set_ui (y, data[i].y);
   287        check_all_inplace (w, y);
   288      }
   289  
   290    mpz_clear (w);
   291    mpz_clear (y);
   292  }
   293  
   294  void
   295  check_data (void)
   296  {
   297    static const struct {
   298      mp_limb_t  w[6];
   299      mp_limb_t  x[6];
   300      mp_limb_t  y[6];
   301  
   302    } data[] = {
   303  
   304      /* reducing to zero */
   305      { { 1 }, { 1 }, { 1 } },
   306      { { 2 }, { 1 }, { 2 } },
   307      { { 0,1 }, { 0,1 }, { 1 } },
   308  
   309      /* reducing to 1 */
   310      { { 0,1 },       { M },       { 1 } },
   311      { { 0,0,1 },     { M,M },     { 1 } },
   312      { { 0,0,0,1 },   { M,M,M },   { 1 } },
   313      { { 0,0,0,0,1 }, { M,M,M,M }, { 1 } },
   314  
   315      /* reducing to -1 */
   316      { { M },       { 0,1 },       { 1 } },
   317      { { M,M },     { 0,0,1 },     { 1 } },
   318      { { M,M,M },   { 0,0,0,1 },   { 1 } },
   319      { { M,M,M,M }, { 0,0,0,0,1 }, { 1 } },
   320  
   321      /* carry out of addmul */
   322      { { M },     { 1 }, { 1 } },
   323      { { M,M },   { 1 }, { 1 } },
   324      { { M,M,M }, { 1 }, { 1 } },
   325  
   326      /* borrow from submul */
   327      { { 0,1 },     { 1 }, { 1 } },
   328      { { 0,0,1 },   { 1 }, { 1 } },
   329      { { 0,0,0,1 }, { 1 }, { 1 } },
   330  
   331      /* borrow from submul */
   332      { { 0,0,1 },     { 0,1 }, { 1 } },
   333      { { 0,0,0,1 },   { 0,1 }, { 1 } },
   334      { { 0,0,0,0,1 }, { 0,1 }, { 1 } },
   335  
   336      /* more borrow from submul */
   337      { { M }, { 0,1 },       { 1 } },
   338      { { M }, { 0,0,1 },     { 1 } },
   339      { { M }, { 0,0,0,1 },   { 1 } },
   340      { { M }, { 0,0,0,0,1 }, { 1 } },
   341  
   342      /* big borrow from submul */
   343      { { 0,0,1 },     { M,M }, { M } },
   344      { { 0,0,0,1 },   { M,M }, { M } },
   345      { { 0,0,0,0,1 }, { M,M }, { M } },
   346  
   347      /* small w */
   348      { { 0,1 }, { M,M },       { M } },
   349      { { 0,1 }, { M,M,M },     { M } },
   350      { { 0,1 }, { M,M,M,M },   { M } },
   351      { { 0,1 }, { M,M,M,M,M }, { M } },
   352    };
   353  
   354    mpz_t  w, x, y;
   355    int    i;
   356  
   357    mpz_init (w);
   358    mpz_init (x);
   359    mpz_init (y);
   360  
   361    for (i = 0; i < numberof (data); i++)
   362      {
   363        mpz_set_n (w, data[i].w, (mp_size_t) numberof(data[i].w));
   364        mpz_set_n (x, data[i].x, (mp_size_t) numberof(data[i].x));
   365        mpz_set_n (y, data[i].y, (mp_size_t) numberof(data[i].y));
   366        check_all (w, x, y);
   367      }
   368  
   369    mpz_clear (w);
   370    mpz_clear (x);
   371    mpz_clear (y);
   372  }
   373  
   374  
   375  void
   376  check_random (int argc, char *argv[])
   377  {
   378    gmp_randstate_ptr rands = RANDS;
   379    mpz_t  w, x, y;
   380    int    i, reps = 2000;
   381  
   382    mpz_init (w);
   383    mpz_init (x);
   384    mpz_init (y);
   385  
   386    if (argc == 2)
   387      reps = atoi (argv[1]);
   388  
   389    for (i = 0; i < reps; i++)
   390      {
   391        mpz_errandomb (w, rands, 5*GMP_LIMB_BITS);
   392        mpz_errandomb (x, rands, 5*GMP_LIMB_BITS);
   393        mpz_errandomb (y, rands, 5*GMP_LIMB_BITS);
   394        check_all (w, x, y);
   395        check_all_inplace (w, y);
   396  
   397        mpz_errandomb (w, rands, 5*GMP_LIMB_BITS);
   398        mpz_errandomb (x, rands, 5*GMP_LIMB_BITS);
   399        mpz_errandomb (y, rands, BITS_PER_ULONG);
   400        check_all (w, x, y);
   401        check_all_inplace (w, y);
   402      }
   403  
   404    mpz_clear (w);
   405    mpz_clear (x);
   406    mpz_clear (y);
   407  }
   408  
   409  
   410  int
   411  main (int argc, char *argv[])
   412  {
   413    tests_start ();
   414    mp_trace_base = -16;
   415  
   416    check_data ();
   417    check_data_inplace_ui ();
   418    check_random (argc, argv);
   419  
   420    tests_end ();
   421    exit (0);
   422  }