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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpf_sub.
  2. Copyright 1996, 2001, 2004 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 "gmp.h"
  17. #include "gmp-impl.h"
  18. #include "tests.h"
  19. #ifndef SIZE
  20. #define SIZE 16
  21. #endif
  22. void
  23. check_rand (int argc, char **argv)
  24. {
  25.   mp_size_t size;
  26.   mp_exp_t exp;
  27.   int reps = 20000;
  28.   int i;
  29.   mpf_t u, v, w, wref;
  30.   mp_size_t bprec = 100;
  31.   mpf_t rerr, max_rerr, limit_rerr;
  32.   if (argc > 1)
  33.     {
  34.       reps = strtol (argv[1], 0, 0);
  35.       if (argc > 2)
  36. bprec = strtol (argv[2], 0, 0);
  37.     }
  38.   mpf_set_default_prec (bprec);
  39.   mpf_init_set_ui (limit_rerr, 1);
  40.   mpf_div_2exp (limit_rerr, limit_rerr, bprec);
  41. #if VERBOSE
  42.   mpf_dump (limit_rerr);
  43. #endif
  44.   mpf_init (rerr);
  45.   mpf_init_set_ui (max_rerr, 0);
  46.   mpf_init (u);
  47.   mpf_init (v);
  48.   mpf_init (w);
  49.   mpf_init (wref);
  50.   for (i = 0; i < reps; i++)
  51.     {
  52.       size = urandom () % (2 * SIZE) - SIZE;
  53.       exp = urandom () % SIZE;
  54.       mpf_random2 (u, size, exp);
  55.       size = urandom () % (2 * SIZE) - SIZE;
  56.       exp = urandom () % SIZE;
  57.       mpf_random2 (v, size, exp);
  58.       if ((urandom () & 1) != 0)
  59. mpf_add_ui (u, v, 1);
  60.       else if ((urandom () & 1) != 0)
  61. mpf_sub_ui (u, v, 1);
  62.       mpf_sub (w, u, v);
  63.       refmpf_sub (wref, u, v);
  64.       mpf_reldiff (rerr, w, wref);
  65.       if (mpf_cmp (rerr, max_rerr) > 0)
  66. {
  67.   mpf_set (max_rerr, rerr);
  68. #if VERBOSE
  69.   mpf_dump (max_rerr);
  70. #endif
  71.   if (mpf_cmp (rerr, limit_rerr) > 0)
  72.     {
  73.       printf ("ERROR after %d testsn", i);
  74.       printf ("   u = "); mpf_dump (u);
  75.       printf ("   v = "); mpf_dump (v);
  76.       printf ("wref = "); mpf_dump (wref);
  77.       printf ("   w = "); mpf_dump (w);
  78.       abort ();
  79.     }
  80. }
  81.     }
  82.   mpf_clear (limit_rerr);
  83.   mpf_clear (rerr);
  84.   mpf_clear (max_rerr);
  85.   mpf_clear (u);
  86.   mpf_clear (v);
  87.   mpf_clear (w);
  88.   mpf_clear (wref);
  89. }
  90. void
  91. check_data (void)
  92. {
  93.   static const struct {
  94.     struct {
  95.       int        exp, size;
  96.       mp_limb_t  d[10];
  97.     } x, y, want;
  98.   } data[] = {
  99.     { { 123, 2, { 8, 9 } },             { 123, 1, { 9 } }, { 122, 1, { 8 } } },
  100.     /* f - f == 0, various sizes.
  101.        These exercise a past problem (gmp 4.1.3 and earlier) where the
  102.        result exponent was not zeroed on a zero result like this.  */
  103.     { { 0, 0 }, { 0, 0 }, { 0, 0 } },
  104.     { { 99, 1, { 1 } },             { 99, 1, { 1 } },             { 0, 0 } },
  105.     { { 99, 2, { 123, 456 } },      { 99, 2, { 123, 456 } },      { 0, 0 } },
  106.     { { 99, 3, { 123, 456, 789 } }, { 99, 3, { 123, 456, 789 } }, { 0, 0 } },
  107.     /* High limbs cancel, leaving just the low limbs of the longer operand.
  108.        This exercises a past problem (gmp 4.1.3 and earlier) where high zero
  109.        limbs on the remainder were not stripped before truncating to the
  110.        destination, causing loss of precision.  */
  111.     { { 123, 2, { 8, 9 } },             { 123, 1, { 9 } }, { 122, 1, { 8 } } },
  112.     { { 123, 3, { 8, 0, 9 } },          { 123, 1, { 9 } }, { 121, 1, { 8 } } },
  113.     { { 123, 4, { 8, 0, 0, 9 } },       { 123, 1, { 9 } }, { 120, 1, { 8 } } },
  114.     { { 123, 5, { 8, 0, 0, 0, 9 } },    { 123, 1, { 9 } }, { 119, 1, { 8 } } },
  115.     { { 123, 6, { 8, 0, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 118, 1, { 8 } } },
  116.   };
  117.   mpf_t  x, y, got, want;
  118.   int  i, swap;
  119.   mp_trace_base = 16;
  120.   mpf_init (got);
  121.   for (i = 0; i < numberof (data); i++)
  122.     {
  123.       for (swap = 0; swap <= 1; swap++)
  124.         {
  125.           PTR(x) = (mp_ptr) data[i].x.d;
  126.           SIZ(x) = data[i].x.size;
  127.           EXP(x) = data[i].x.exp;
  128.           PREC(x) = numberof (data[i].x.d);
  129.           MPF_CHECK_FORMAT (x);
  130.           PTR(y) = (mp_ptr) data[i].y.d;
  131.           SIZ(y) = data[i].y.size;
  132.           EXP(y) = data[i].y.exp;
  133.           PREC(y) = numberof (data[i].y.d);
  134.           MPF_CHECK_FORMAT (y);
  135.           PTR(want) = (mp_ptr) data[i].want.d;
  136.           SIZ(want) = data[i].want.size;
  137.           EXP(want) = data[i].want.exp;
  138.           PREC(want) = numberof (data[i].want.d);
  139.           MPF_CHECK_FORMAT (want);
  140.           if (swap)
  141.             {
  142.               mpf_swap (x, y);
  143.               SIZ(want) = - SIZ(want);
  144.             }
  145.           mpf_sub (got, x, y);
  146. /*           MPF_CHECK_FORMAT (got); */
  147.           if (mpf_cmp (got, want) != 0)
  148.             {
  149.               printf ("check_data() wrong reault at data[%d] (operands%s swapped)n", i, swap ? "" : " not");
  150.               mpf_trace ("x   ", x);
  151.               mpf_trace ("y   ", y);
  152.               mpf_trace ("got ", got);
  153.               mpf_trace ("want", want);
  154.               abort ();
  155.             }
  156.         }
  157.     }
  158.   mpf_clear (got);
  159. }
  160. int
  161. main (int argc, char **argv)
  162. {
  163.   tests_start ();
  164.   check_data ();
  165.   check_rand (argc, argv);
  166.   tests_end ();
  167.   exit (0);
  168. }