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