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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_tdiv_qr, mpz_tdiv_q,
  2.    mpz_tdiv_r, mpz_mul.
  3. Copyright 1991, 1993, 1994, 1996, 1997, 2000, 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 dump_abort __GMP_PROTO ((mpz_t, mpz_t));
  21. void debug_mp __GMP_PROTO ((mpz_t, int));
  22. int
  23. main (int argc, char **argv)
  24. {
  25.   mpz_t dividend, divisor;
  26.   mpz_t quotient, remainder;
  27.   mpz_t quotient2, remainder2;
  28.   mpz_t temp;
  29.   mp_size_t dividend_size, divisor_size;
  30.   int i;
  31.   int reps = 1000;
  32.   gmp_randstate_ptr rands;
  33.   mpz_t bs;
  34.   unsigned long bsi, size_range;
  35.   tests_start ();
  36.   TESTS_REPS (reps, argv, argc);
  37.   rands = RANDS;
  38.   mpz_init (bs);
  39.   mpz_init (dividend);
  40.   mpz_init (divisor);
  41.   mpz_init (quotient);
  42.   mpz_init (remainder);
  43.   mpz_init (quotient2);
  44.   mpz_init (remainder2);
  45.   mpz_init (temp);
  46.   for (i = 0; i < reps; i++)
  47.     {
  48.       mpz_urandomb (bs, rands, 32);
  49.       size_range = mpz_get_ui (bs) % 18 + 2; /* 0..524288 bit operands */
  50.       do
  51. {
  52.   mpz_urandomb (bs, rands, size_range);
  53.   divisor_size = mpz_get_ui (bs);
  54.   mpz_rrandomb (divisor, rands, divisor_size);
  55. }
  56.       while (mpz_sgn (divisor) == 0);
  57.       mpz_urandomb (bs, rands, size_range);
  58.       dividend_size = mpz_get_ui (bs) + divisor_size;
  59.       mpz_rrandomb (dividend, rands, dividend_size);
  60.       mpz_urandomb (bs, rands, 2);
  61.       bsi = mpz_get_ui (bs);
  62.       if ((bsi & 1) != 0)
  63. mpz_neg (dividend, dividend);
  64.       if ((bsi & 2) != 0)
  65. mpz_neg (divisor, divisor);
  66.       /* printf ("%ld %ldn", SIZ (dividend), SIZ (divisor)); */
  67.       mpz_tdiv_qr (quotient, remainder, dividend, divisor);
  68.       mpz_tdiv_q (quotient2, dividend, divisor);
  69.       mpz_tdiv_r (remainder2, 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 (dividend, divisor);
  74.       if (mpz_cmp (remainder, remainder2) != 0)
  75. dump_abort (dividend, divisor);
  76.       /* Check if the sign of the quotient is correct.  */
  77.       if (mpz_cmp_ui (quotient, 0) != 0)
  78. if ((mpz_cmp_ui (quotient, 0) < 0)
  79.     != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
  80. dump_abort (dividend, divisor);
  81.       /* Check if the remainder has the same sign as the dividend
  82.  (quotient rounded towards 0).  */
  83.       if (mpz_cmp_ui (remainder, 0) != 0)
  84. if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
  85.   dump_abort (dividend, divisor);
  86.       mpz_mul (temp, quotient, divisor);
  87.       mpz_add (temp, temp, remainder);
  88.       if (mpz_cmp (temp, dividend) != 0)
  89. dump_abort (dividend, divisor);
  90.       mpz_abs (temp, divisor);
  91.       mpz_abs (remainder, remainder);
  92.       if (mpz_cmp (remainder, temp) >= 0)
  93. dump_abort (dividend, divisor);
  94.     }
  95.   mpz_clear (bs);
  96.   mpz_clear (dividend);
  97.   mpz_clear (divisor);
  98.   mpz_clear (quotient);
  99.   mpz_clear (remainder);
  100.   mpz_clear (quotient2);
  101.   mpz_clear (remainder2);
  102.   mpz_clear (temp);
  103.   tests_end ();
  104.   exit (0);
  105. }
  106. void
  107. dump_abort (mpz_t dividend, mpz_t divisor)
  108. {
  109.   fprintf (stderr, "ERRORn");
  110.   fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
  111.   fprintf (stderr, "divisor  = "); debug_mp (divisor, -16);
  112.   abort();
  113. }
  114. void
  115. debug_mp (mpz_t x, int base)
  116. {
  117.   mpz_out_str (stderr, base, x); fputc ('n', stderr);
  118. }