t-aorsmul.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:9k
源码类别:

数学计算

开发平台:

Unix_Linux

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