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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpz_popcount.
  2. Copyright 2001, 2005 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. void
  20. check_onebit (void)
  21. {
  22.   mpz_t          n;
  23.   unsigned long  i, got;
  24.   mpz_init (n);
  25.   for (i = 0; i < 5 * GMP_LIMB_BITS; i++)
  26.     {
  27.       mpz_setbit (n, i);
  28.       got = mpz_popcount (n);
  29.       if (got != 1)
  30. {
  31.   printf ("mpz_popcount wrong on single bit at %lun", i);
  32.   printf ("   got %lu, want 1n", got);
  33.   abort();
  34. }
  35.       mpz_clrbit (n, i);
  36.     }
  37.   mpz_clear (n);
  38. }
  39. void
  40. check_data (void)
  41. {
  42.   static const struct {
  43.     const char     *n;
  44.     unsigned long  want;
  45.   } data[] = {
  46.     { "-1", ~ (unsigned long) 0 },
  47.     { "-12345678", ~ (unsigned long) 0 },
  48.     { "0", 0 },
  49.     { "1", 1 },
  50.     { "3", 2 },
  51.     { "5", 2 },
  52.     { "0xFFFF", 16 },
  53.     { "0xFFFFFFFF", 32 },
  54.     { "0xFFFFFFFFFFFFFFFF", 64 },
  55.     { "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 128 },
  56.   };
  57.   unsigned long   got;
  58.   int    i;
  59.   mpz_t  n;
  60.   mpz_init (n);
  61.   for (i = 0; i < numberof (data); i++)
  62.     {
  63.       mpz_set_str_or_abort (n, data[i].n, 0);
  64.       got = mpz_popcount (n);
  65.       if (got != data[i].want)
  66. {
  67.   printf ("mpz_popcount wrong at data[%d]n", i);
  68.   printf ("   n     "%s"n", data[i].n);
  69.   printf ("         ");   mpz_out_str (stdout, 10, n); printf ("n");
  70.   printf ("         0x"); mpz_out_str (stdout, 16, n); printf ("n");
  71.   printf ("   got   %lun", got);
  72.   printf ("   want  %lun", data[i].want);
  73.   abort();
  74. }
  75.     }
  76.   mpz_clear (n);
  77. }
  78. unsigned long
  79. refmpz_popcount (mpz_t arg)
  80. {
  81.   mp_size_t n, i;
  82.   unsigned long cnt;
  83.   mp_limb_t x;
  84.   n = SIZ(arg);
  85.   if (n < 0)
  86.     return ~(unsigned long) 0;
  87.   cnt = 0;
  88.   for (i = 0; i < n; i++)
  89.     {
  90.       x = PTR(arg)[i];
  91.       while (x != 0)
  92. {
  93.   cnt += (x & 1);
  94.   x >>= 1;
  95. }
  96.     }
  97.   return cnt;
  98. }
  99. void
  100. check_random (void)
  101. {
  102.   gmp_randstate_ptr rands;
  103.   mpz_t bs;
  104.   mpz_t arg;
  105.   unsigned long arg_size, size_range;
  106.   unsigned long got, ref;
  107.   int i;
  108.   rands = RANDS;
  109.   mpz_init (bs);
  110.   mpz_init (arg);
  111.   for (i = 0; i < 10000; i++)
  112.     {
  113.       mpz_urandomb (bs, rands, 32);
  114.       size_range = mpz_get_ui (bs) % 11 + 2; /* 0..4096 bit operands */
  115.       mpz_urandomb (bs, rands, size_range);
  116.       arg_size = mpz_get_ui (bs);
  117.       mpz_rrandomb (arg, rands, arg_size);
  118.       got = mpz_popcount (arg);
  119.       ref = refmpz_popcount (arg);
  120.       if (got != ref)
  121. {
  122.   printf ("mpz_popcount wrong on randomn");
  123.   printf ("         ");   mpz_out_str (stdout, 10, arg); printf ("n");
  124.   printf ("         0x"); mpz_out_str (stdout, 16, arg); printf ("n");
  125.   printf ("   got   %lun", got);
  126.   printf ("   want  %lun", ref);
  127.   abort();
  128.   abort ();
  129. }
  130.     }
  131.   mpz_clear (arg);
  132.   mpz_clear (bs);
  133. }
  134. int
  135. main (void)
  136. {
  137.   tests_start ();
  138.   check_onebit ();
  139.   check_data ();
  140.   check_random ();
  141.   tests_end ();
  142.   exit (0);
  143. }