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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpz_set_d and mpz_init_set_d.
  2. Copyright 2000, 2001, 2002, 2003, 2006 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_data (void)
  21. {
  22.   static const struct {
  23.     double     d;
  24.     mp_size_t  want_size;
  25.     mp_limb_t  want_data[2];
  26.   } data[] = {
  27.     {  0.0,  0 },
  28.     {  1.0,  1, { 1 } },
  29.     { -1.0, -1, { 1 } },
  30.     {  123.0,  1, { 123 } },
  31.     { -123.0, -1, { 123 } },
  32.     { 1e-1, 0, { 0 } },
  33.     { -1e-1, 0, { 0 } },
  34.     { 2.328306436538696e-10, 0, { 0 } },
  35.     { -2.328306436538696e-10, 0, { 0 } },
  36.     { 5.421010862427522e-20, 0, { 0 } },
  37.     { -5.421010862427522e-20, 0, { 0 } },
  38.     { 2.938735877055719e-39, 0, { 0 } },
  39.     { -2.938735877055719e-39, 0, { 0 } },
  40.   };
  41.   mpz_t  z;
  42.   int    i;
  43.   for (i = 0; i < numberof (data); i++)
  44.     {
  45.       mpz_init (z);
  46.       mpz_set_d (z, data[i].d);
  47.       MPZ_CHECK_FORMAT (z);
  48.       if (z->_mp_size != data[i].want_size
  49.           || refmpn_cmp_allowzero (z->_mp_d, data[i].want_data,
  50.                                    ABS (data[i].want_size)) != 0)
  51.         {
  52.           printf ("mpz_set_d wrong on data[%d]n", i);
  53.         bad:
  54.           d_trace   ("  d  ", data[i].d);
  55.           printf    ("  got  size %ldn", (long) z->_mp_size);
  56.           printf    ("  want size %ldn", (long) data[i].want_size);
  57.           mpn_trace ("  got  z", z->_mp_d, z->_mp_size);
  58.           mpn_trace ("  want z", data[i].want_data, data[i].want_size);
  59.           abort();
  60.         }
  61.       mpz_clear (z);
  62.       mpz_init_set_d (z, data[i].d);
  63.       MPZ_CHECK_FORMAT (z);
  64.       if (z->_mp_size != data[i].want_size
  65.           || refmpn_cmp_allowzero (z->_mp_d, data[i].want_data,
  66.                                    ABS (data[i].want_size)) != 0)
  67.         {
  68.           printf ("mpz_init_set_d wrong on data[%d]n", i);
  69.           goto bad;
  70.         }
  71.       mpz_clear (z);
  72.     }
  73. }
  74. /* Try mpz_set_d on values 2^i+1, while such a value fits a double. */
  75. void
  76. check_2n_plus_1 (void)
  77. {
  78.   volatile double  p, d, diff;
  79.   mpz_t  want, got;
  80.   int    i;
  81.   mpz_init (want);
  82.   mpz_init (got);
  83.   p = 1.0;
  84.   mpz_set_ui (want, 2L);  /* gives 3 on first step */
  85.   for (i = 1; i < 500; i++)
  86.     {
  87.       mpz_mul_2exp (want, want, 1L);
  88.       mpz_sub_ui (want, want, 1L);   /* want = 2^i+1 */
  89.       p *= 2.0;  /* p = 2^i */
  90.       d = p + 1.0;
  91.       diff = d - p;
  92.       if (diff != 1.0)
  93.         break;   /* rounding occurred, stop now */
  94.       mpz_set_d (got, d);
  95.       MPZ_CHECK_FORMAT (got);
  96.       if (mpz_cmp (got, want) != 0)
  97.         {
  98.           printf ("mpz_set_d wrong on 2^%d+1n", i);
  99.           d_trace   ("  d ", d);
  100.           mpz_trace ("  got  ", got);
  101.           mpz_trace ("  want ", want);
  102.           abort ();
  103.         }
  104.     }
  105.   mpz_clear (want);
  106.   mpz_clear (got);
  107. }
  108. int
  109. main (void)
  110. {
  111.   tests_start ();
  112.   check_data ();
  113.   check_2n_plus_1 ();
  114.   tests_end ();
  115.   exit (0);
  116. }