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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpf_div.
  2. Copyright 2004 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_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpf_srcptr v)
  21. {
  22.   if (! refmpf_validate_division ("mpf_div", got, u, v))
  23.     {
  24.       mp_trace_base = -16;
  25.       mpf_trace ("  u", u);
  26.       mpf_trace ("  v", v);
  27.       printf    ("  %sn", desc);
  28.       abort ();
  29.     }
  30. }
  31. void
  32. check_rand (void)
  33. {
  34.   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  35.   gmp_randstate_ptr  rands = RANDS;
  36.   unsigned long  prec;
  37.   mpf_t  got, u, v;
  38.   int    i;
  39.   mpf_init (got);
  40.   mpf_init (u);
  41.   mpf_init (v);
  42.   /* separate */
  43.   for (i = 0; i < 100; i++)
  44.     {
  45.       /* got precision */
  46.       prec = min_prec + gmp_urandomm_ui (rands, 15L);
  47.       refmpf_set_prec_limbs (got, prec);
  48.       /* u */
  49.       prec = min_prec + gmp_urandomm_ui (rands, 15L);
  50.       refmpf_set_prec_limbs (u, prec);
  51.       do {
  52.         mpf_random2 (u, PREC(u), (mp_exp_t) 20);
  53.       } while (SIZ(u) == 0);
  54.       if (gmp_urandomb_ui (rands, 1L))
  55.         mpf_neg (u, u);
  56.       /* v */
  57.       prec = min_prec + gmp_urandomm_ui (rands, 15L);
  58.       refmpf_set_prec_limbs (v, prec);
  59.       do {
  60.         mpf_random2 (v, PREC(v), (mp_exp_t) 20);
  61.       } while (SIZ(v) == 0);
  62.       if (gmp_urandomb_ui (rands, 1L))
  63.         mpf_neg (v, v);
  64.       switch (i % 3) {
  65.       case 0:
  66.         mpf_div (got, u, v);
  67.         check_one ("separate", got, u, v);
  68.         break;
  69.       case 1:
  70.         prec = refmpf_set_overlap (got, u);
  71.         mpf_div (got, got, v);
  72.         check_one ("dst == u", got, u, v);
  73.         mpf_set_prec_raw (got, prec);
  74.         break;
  75.       case 2:
  76.         prec = refmpf_set_overlap (got, v);
  77.         mpf_div (got, u, got);
  78.         check_one ("dst == v", got, u, v);
  79.         mpf_set_prec_raw (got, prec);
  80.         break;
  81.       }
  82.     }
  83.   mpf_clear (got);
  84.   mpf_clear (u);
  85.   mpf_clear (v);
  86. }
  87. /* Exercise calls mpf(x,x,x) */
  88. void
  89. check_reuse_three (void)
  90. {
  91.   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  92.   gmp_randstate_ptr  rands = RANDS;
  93.   unsigned long  result_prec, input_prec, set_prec;
  94.   mpf_t  got;
  95.   int    i;
  96.   mpf_init (got);
  97.   for (i = 0; i < 8; i++)
  98.     {
  99.       result_prec = min_prec + gmp_urandomm_ui (rands, 15L);
  100.       input_prec = min_prec + gmp_urandomm_ui (rands, 15L);
  101.       set_prec = MAX (result_prec, input_prec);
  102.       refmpf_set_prec_limbs (got, set_prec);
  103.       /* input, non-zero, possibly negative */
  104.       PREC(got) = input_prec;
  105.       do {
  106.         mpf_random2 (got, input_prec, (mp_exp_t) 20);
  107.       } while (SIZ(got) == 0);
  108.       if (gmp_urandomb_ui (rands, 1L))
  109.         mpf_neg (got, got);
  110.       PREC(got) = result_prec;
  111.       mpf_div (got, got, got);
  112.       /* expect exactly 1.0 always */
  113.       ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0);
  114.       PREC(got) = set_prec;
  115.     }
  116.   mpf_clear (got);
  117. }
  118. void
  119. check_various (void)
  120. {
  121.   mpf_t got, u, v;
  122.   mpf_init (got);
  123.   mpf_init (u);
  124.   mpf_init (v);
  125.   /* 100/4 == 25 */
  126.   mpf_set_prec (got, 20L);
  127.   mpf_set_ui (u, 100L);
  128.   mpf_set_ui (v, 4L);
  129.   mpf_div (got, u, v);
  130.   MPF_CHECK_FORMAT (got);
  131.   ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
  132.   /* 1/(2^n+1), a case where truncating the divisor would be wrong */
  133.   mpf_set_prec (got, 500L);
  134.   mpf_set_prec (v, 900L);
  135.   mpf_set_ui (v, 1L);
  136.   mpf_mul_2exp (v, v, 800L);
  137.   mpf_add_ui (v, v, 1L);
  138.   mpf_div (got, u, v);
  139.   check_one ("1/2^n+1, separate", got, u, v);
  140.   mpf_clear (got);
  141.   mpf_clear (u);
  142.   mpf_clear (v);
  143. }
  144. int
  145. main (void)
  146. {
  147.   tests_start ();
  148.   check_various ();
  149.   check_rand ();
  150.   check_reuse_three ();
  151.   tests_end ();
  152.   exit (0);
  153. }