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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_cdiv_qr_ui, mpz_cdiv_q_ui,
  2.    mpz_cdiv_r_ui, , mpz_cdiv_ui, mpz_mul_ui.
  3. Copyright 1993, 1994, 1996, 2000, 2001, 2002 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 dump_abort __GMP_PROTO ((char *, mpz_t, unsigned long));
  21. void debug_mp __GMP_PROTO ((mpz_t, int));
  22. int
  23. main (int argc, char **argv)
  24. {
  25.   mpz_t dividend;
  26.   mpz_t quotient, remainder;
  27.   mpz_t quotient2, remainder2;
  28.   mpz_t temp;
  29.   mp_size_t dividend_size;
  30.   unsigned long divisor;
  31.   int i;
  32.   int reps = 10000;
  33.   gmp_randstate_ptr rands;
  34.   mpz_t bs;
  35.   unsigned long bsi, size_range;
  36.   unsigned long r_rq, r_q, r_r, r;
  37.   tests_start ();
  38.   rands = RANDS;
  39.   mpz_init (bs);
  40.   if (argc == 2)
  41.      reps = atoi (argv[1]);
  42.   mpz_init (dividend);
  43.   mpz_init (quotient);
  44.   mpz_init (remainder);
  45.   mpz_init (quotient2);
  46.   mpz_init (remainder2);
  47.   mpz_init (temp);
  48.   for (i = 0; i < reps; i++)
  49.     {
  50.       mpz_urandomb (bs, rands, 32);
  51.       size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */
  52.       do
  53. {
  54.   mpz_rrandomb (bs, rands, 64);
  55.   divisor = mpz_get_ui (bs);
  56. }
  57.       while (divisor == 0);
  58.       mpz_urandomb (bs, rands, size_range);
  59.       dividend_size = mpz_get_ui (bs);
  60.       mpz_rrandomb (dividend, rands, dividend_size);
  61.       mpz_urandomb (bs, rands, 2);
  62.       bsi = mpz_get_ui (bs);
  63.       if ((bsi & 1) != 0)
  64. mpz_neg (dividend, dividend);
  65.       /* printf ("%ldn", SIZ (dividend)); */
  66.       r_rq = mpz_cdiv_qr_ui (quotient, remainder, dividend, divisor);
  67.       r_q = mpz_cdiv_q_ui (quotient2, dividend, divisor);
  68.       r_r = mpz_cdiv_r_ui (remainder2, dividend, divisor);
  69.       r = mpz_cdiv_ui (dividend, divisor);
  70.       /* First determine that the quotients and remainders computed
  71.  with different functions are equal.  */
  72.       if (mpz_cmp (quotient, quotient2) != 0)
  73. dump_abort ("quotients from mpz_cdiv_qr_ui and mpz_cdiv_q_ui differ",
  74.     dividend, divisor);
  75.       if (mpz_cmp (remainder, remainder2) != 0)
  76. dump_abort ("remainders from mpz_cdiv_qr_ui and mpz_cdiv_r_ui differ",
  77.     dividend, divisor);
  78.       /* Check if the sign of the quotient is correct.  */
  79.       if (mpz_cmp_ui (quotient, 0) != 0)
  80. if ((mpz_cmp_ui (quotient, 0) < 0)
  81.     != (mpz_cmp_ui (dividend, 0) < 0))
  82. dump_abort ("quotient sign wrong", dividend, divisor);
  83.       /* Check if the remainder has the opposite sign as the (positive) divisor
  84.  (quotient rounded towards minus infinity).  */
  85.       if (mpz_cmp_ui (remainder, 0) != 0)
  86. if (mpz_cmp_ui (remainder, 0) > 0)
  87.   dump_abort ("remainder sign wrong", dividend, divisor);
  88.       mpz_mul_ui (temp, quotient, divisor);
  89.       mpz_add (temp, temp, remainder);
  90.       if (mpz_cmp (temp, dividend) != 0)
  91. dump_abort ("n mod d != n - [n/d]*d", dividend, divisor);
  92.       mpz_abs (remainder, remainder);
  93.       if (mpz_cmp_ui (remainder, divisor) >= 0)
  94. dump_abort ("remainder greater than divisor", dividend, divisor);
  95.       if (mpz_cmp_ui (remainder, r_rq) != 0)
  96. dump_abort ("remainder returned from mpz_cdiv_qr_ui is wrong",
  97.     dividend, divisor);
  98.       if (mpz_cmp_ui (remainder, r_q) != 0)
  99. dump_abort ("remainder returned from mpz_cdiv_q_ui is wrong",
  100.     dividend, divisor);
  101.       if (mpz_cmp_ui (remainder, r_r) != 0)
  102. dump_abort ("remainder returned from mpz_cdiv_r_ui is wrong",
  103.     dividend, divisor);
  104.       if (mpz_cmp_ui (remainder, r) != 0)
  105. dump_abort ("remainder returned from mpz_cdiv_ui is wrong",
  106.     dividend, divisor);
  107.     }
  108.   mpz_clear (bs);
  109.   mpz_clear (dividend);
  110.   mpz_clear (quotient);
  111.   mpz_clear (remainder);
  112.   mpz_clear (quotient2);
  113.   mpz_clear (remainder2);
  114.   mpz_clear (temp);
  115.   tests_end ();
  116.   exit (0);
  117. }
  118. void
  119. dump_abort (char *str, mpz_t dividend, unsigned long divisor)
  120. {
  121.   fprintf (stderr, "ERROR: %sn", str);
  122.   fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
  123.   fprintf (stderr, "divisor  = %lXn", divisor);
  124.   abort();
  125. }
  126. void
  127. debug_mp (mpz_t x, int base)
  128. {
  129.   mpz_out_str (stderr, base, x); fputc ('n', stderr);
  130. }