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

数学计算

开发平台:

Unix_Linux

  1. /* test mpz_congruent_2exp_p */
  2. /*
  3. Copyright 2001 Free Software Foundation, Inc.
  4. This file is part of the GNU MP Library.
  5. The GNU MP Library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU Lesser General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or (at your
  8. option) any later version.
  9. The GNU MP Library is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  12. License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include "gmp.h"
  18. #include "gmp-impl.h"
  19. #include "tests.h"
  20. void
  21. check_one (mpz_srcptr a, mpz_srcptr c, unsigned long d, int want)
  22. {
  23.   mpz_t  diff, d2exp;
  24.   int    got;
  25.   int    swap;
  26.   for (swap = 0; swap <= 1; swap++)
  27.     {
  28.       got = (mpz_congruent_2exp_p (a, c, d) != 0);
  29.       if (want != got)
  30.         {
  31.           mpz_init (diff);
  32.           mpz_init (d2exp);
  33.           mpz_sub (diff, a, c);
  34.           mpz_set_ui (d2exp, 1L);
  35.           mpz_mul_2exp (d2exp, d2exp, d);
  36.           printf ("mpz_congruent_2exp_p wrongn");
  37.           printf ("   expected %d got %dn", want, got);
  38.           mpz_trace ("   a", a);
  39.           mpz_trace ("   c", c);
  40.           mpz_trace (" a-c", diff);
  41.           mpz_trace (" 2^d", d2exp);
  42.           printf    ("   d=%lun", d);
  43.           mp_trace_base = -16;
  44.           mpz_trace ("   a", a);
  45.           mpz_trace ("   c", c);
  46.           mpz_trace (" a-c", diff);
  47.           mpz_trace (" 2^d", d2exp);
  48.           printf    ("   d=0x%lXn", d);
  49.           abort ();
  50.         }
  51.       MPZ_SRCPTR_SWAP (a, c);
  52.     }
  53. }
  54. void
  55. check_data (void)
  56. {
  57.   static const struct {
  58.     const char     *a;
  59.     const char     *c;
  60.     unsigned long  d;
  61.     int            want;
  62.   } data[] = {
  63.     /* anything is congruent mod 1 */
  64.     { "0", "0", 0, 1 },
  65.     { "1", "0", 0, 1 },
  66.     { "0", "1", 0, 1 },
  67.     { "123", "456", 0, 1 },
  68.     { "0x123456789123456789", "0x987654321987654321", 0, 1 },
  69.   };
  70.   mpz_t   a, c;
  71.   int     i;
  72.   mpz_init (a);
  73.   mpz_init (c);
  74.   for (i = 0; i < numberof (data); i++)
  75.     {
  76.       mpz_set_str_or_abort (a, data[i].a, 0);
  77.       mpz_set_str_or_abort (c, data[i].c, 0);
  78.       check_one (a, c, data[i].d, data[i].want);
  79.     }
  80.   mpz_clear (a);
  81.   mpz_clear (c);
  82. }
  83. void
  84. check_random (int argc, char *argv[])
  85. {
  86.   gmp_randstate_ptr rands = RANDS;
  87.   unsigned long  d;
  88.   mpz_t  a, c, ra, rc;
  89.   int    i;
  90.   int    want;
  91.   int    reps = 5000;
  92.   if (argc >= 2)
  93.     reps = atoi (argv[1]);
  94.   mpz_init (a);
  95.   mpz_init (c);
  96.   mpz_init (ra);
  97.   mpz_init (rc);
  98.   for (i = 0; i < reps; i++)
  99.     {
  100.       mpz_errandomb (a, rands, 8*GMP_LIMB_BITS);
  101.       mpz_errandomb (c, rands, 8*GMP_LIMB_BITS);
  102.       d = urandom() % (8*GMP_LIMB_BITS);
  103.       mpz_mul_2exp (a, a, urandom() % (2*GMP_LIMB_BITS));
  104.       mpz_mul_2exp (c, c, urandom() % (2*GMP_LIMB_BITS));
  105.       mpz_negrandom (a, rands);
  106.       mpz_negrandom (c, rands);
  107.       mpz_fdiv_r_2exp (ra, a, d);
  108.       mpz_fdiv_r_2exp (rc, c, d);
  109.       want = (mpz_cmp (ra, rc) == 0);
  110.       check_one (a, c, d, want);
  111.       mpz_sub (ra, ra, rc);
  112.       mpz_sub (a, a, ra);
  113.       check_one (a, c, d, 1);
  114.     }
  115.   mpz_clear (a);
  116.   mpz_clear (c);
  117.   mpz_clear (ra);
  118.   mpz_clear (rc);
  119. }
  120. int
  121. main (int argc, char *argv[])
  122. {
  123.   tests_start ();
  124.   check_data ();
  125.   check_random (argc, argv);
  126.   tests_end ();
  127.   exit (0);
  128. }