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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_fdiv_qr, mpz_fdiv_q,
  2.    mpz_fdiv_r, mpz_mul.
  3. Copyright 1993, 1994, 1996, 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.   rands = RANDS;
  37.   mpz_init (bs);
  38.   if (argc == 2)
  39.      reps = atoi (argv[1]);
  40.   mpz_init (dividend);
  41.   mpz_init (divisor);
  42.   mpz_init (quotient);
  43.   mpz_init (remainder);
  44.   mpz_init (quotient2);
  45.   mpz_init (remainder2);
  46.   mpz_init (temp);
  47.   for (i = 0; i < reps; i++)
  48.     {
  49.       mpz_urandomb (bs, rands, 32);
  50.       size_range = mpz_get_ui (bs) % 16 + 2; /* 0..131071 bit operands */
  51.       do
  52. {
  53.   mpz_urandomb (bs, rands, size_range);
  54.   divisor_size = mpz_get_ui (bs);
  55.   mpz_rrandomb (divisor, rands, divisor_size);
  56. }
  57.       while (mpz_sgn (divisor) == 0);
  58.       mpz_urandomb (bs, rands, size_range);
  59.       dividend_size = mpz_get_ui (bs) + divisor_size;
  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.       if ((bsi & 2) != 0)
  66. mpz_neg (divisor, divisor);
  67.       /* printf ("%ld %ldn", SIZ (dividend), SIZ (divisor)); */
  68.       mpz_fdiv_qr (quotient, remainder, dividend, divisor);
  69.       mpz_fdiv_q (quotient2, dividend, divisor);
  70.       mpz_fdiv_r (remainder2, dividend, divisor);
  71.       /* First determine that the quotients and remainders computed
  72.  with different functions are equal.  */
  73.       if (mpz_cmp (quotient, quotient2) != 0)
  74. dump_abort (dividend, divisor);
  75.       if (mpz_cmp (remainder, remainder2) != 0)
  76. dump_abort (dividend, divisor);
  77.       /* Check if the sign of the quotient is correct.  */
  78.       if (mpz_cmp_ui (quotient, 0) != 0)
  79. if ((mpz_cmp_ui (quotient, 0) < 0)
  80.     != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
  81. dump_abort (dividend, divisor);
  82.       /* Check if the remainder has the same sign as the divisor
  83.  (quotient rounded towards minus infinity).  */
  84.       if (mpz_cmp_ui (remainder, 0) != 0)
  85. if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (divisor, 0) < 0))
  86.   dump_abort (dividend, divisor);
  87.       mpz_mul (temp, quotient, divisor);
  88.       mpz_add (temp, temp, remainder);
  89.       if (mpz_cmp (temp, dividend) != 0)
  90. dump_abort (dividend, divisor);
  91.       mpz_abs (temp, divisor);
  92.       mpz_abs (remainder, remainder);
  93.       if (mpz_cmp (remainder, temp) >= 0)
  94. dump_abort (dividend, divisor);
  95.     }
  96.   mpz_clear (bs);
  97.   mpz_clear (dividend);
  98.   mpz_clear (divisor);
  99.   mpz_clear (quotient);
  100.   mpz_clear (remainder);
  101.   mpz_clear (quotient2);
  102.   mpz_clear (remainder2);
  103.   mpz_clear (temp);
  104.   tests_end ();
  105.   exit (0);
  106. }
  107. void
  108. dump_abort (mpz_t dividend, mpz_t divisor)
  109. {
  110.   fprintf (stderr, "ERRORn");
  111.   fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
  112.   fprintf (stderr, "divisor  = "); debug_mp (divisor, -16);
  113.   abort();
  114. }
  115. void
  116. debug_mp (mpz_t x, int base)
  117. {
  118.   mpz_out_str (stderr, base, x); fputc ('n', stderr);
  119. }