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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpz_cmp_d and mpz_cmpabs_d.
  2. Copyright 2001, 2002, 2003, 2005 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 <string.h>
  17. #include "gmp.h"
  18. #include "gmp-impl.h"
  19. #include "tests.h"
  20. /* FIXME: Not sure if the tests here are exhaustive.  Ought to try to get
  21.    each possible exit from mpz_cmp_d (and mpz_cmpabs_d) exercised.  */
  22. #define SGN(n)  ((n) > 0 ? 1 : (n) < 0 ? -1 : 0)
  23. void
  24. check_one (const char *name, mpz_srcptr x, double y, int cmp, int cmpabs)
  25. {
  26.   int   got;
  27.   got = mpz_cmp_d (x, y);
  28.   if (SGN(got) != cmp)
  29.     {
  30.       int i;
  31.       printf    ("mpz_cmp_d wrong (from %s)n", name);
  32.       printf    ("  got  %dn", got);
  33.       printf    ("  want %dn", cmp);
  34.     fail:
  35.       mpz_trace ("  x", x);
  36.       printf    ("  y %gn", y);
  37.       mp_trace_base=-16;
  38.       mpz_trace ("  x", x);
  39.       printf    ("  y %gn", y);
  40.       printf    ("  y");
  41.       for (i = 0; i < sizeof(y); i++)
  42.         printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
  43.       printf ("n");
  44.       abort ();
  45.     }
  46.   got = mpz_cmpabs_d (x, y);
  47.   if (SGN(got) != cmpabs)
  48.     {
  49.       printf    ("mpz_cmpabs_d wrongn");
  50.       printf    ("  got  %dn", got);
  51.       printf    ("  want %dn", cmpabs);
  52.       goto fail;
  53.     }
  54. }
  55. void
  56. check_data (void)
  57. {
  58.   static const struct {
  59.     const char  *x;
  60.     double      y;
  61.     int         cmp, cmpabs;
  62.   } data[] = {
  63.     {  "0",  0.0,  0,  0 },
  64.     {  "1",  0.0,  1,  1 },
  65.     { "-1",  0.0, -1,  1 },
  66.     {  "0",  1.0, -1, -1 },
  67.     {  "0", -1.0,  1, -1 },
  68.     {  "0x1000000000000000000000000000000000000000000000000", 0.0,  1, 1 },
  69.     { "-0x1000000000000000000000000000000000000000000000000", 0.0, -1, 1 },
  70.     {  "0",  1e100, -1, -1 },
  71.     {  "0", -1e100,  1, -1 },
  72.     {  "2",  1.5,   1,  1 },
  73.     {  "2", -1.5,   1,  1 },
  74.     { "-2",  1.5,  -1,  1 },
  75.     { "-2", -1.5,  -1,  1 },
  76.   };
  77.   mpz_t  x;
  78.   int    i;
  79.   mpz_init (x);
  80.   for (i = 0; i < numberof (data); i++)
  81.     {
  82.       mpz_set_str_or_abort (x, data[i].x, 0);
  83.       check_one ("check_data", x, data[i].y, data[i].cmp, data[i].cmpabs);
  84.     }
  85.   mpz_clear (x);
  86. }
  87. /* Equality of integers with up to 53 bits */
  88. void
  89. check_onebits (void)
  90. {
  91.   mpz_t   x, x2;
  92.   double  y;
  93.   int     i;
  94.   mpz_init_set_ui (x, 0L);
  95.   mpz_init (x2);
  96.   for (i = 0; i < 512; i++)
  97.     {
  98.       mpz_mul_2exp (x, x, 1);
  99.       mpz_add_ui (x, x, 1L);
  100.       y = mpz_get_d (x);
  101.       mpz_set_d (x2, y);
  102.       /* stop if any truncation is occurring */
  103.       if (mpz_cmp (x, x2) != 0)
  104.         break;
  105.       check_one ("check_onebits", x, y, 0, 0);
  106.       check_one ("check_onebits", x, -y, 1, 0);
  107.       mpz_neg (x, x);
  108.       check_one ("check_onebits", x, y, -1, 0);
  109.       check_one ("check_onebits", x, -y, 0, 0);
  110.       mpz_neg (x, x);
  111.     }
  112.   mpz_clear (x);
  113.   mpz_clear (x2);
  114. }
  115. /* With the mpz differing by 1, in a limb position possibly below the double */
  116. void
  117. check_low_z_one (void)
  118. {
  119.   mpz_t          x;
  120.   double         y;
  121.   unsigned long  i;
  122.   mpz_init (x);
  123.   /* FIXME: It'd be better to base this on the float format. */
  124. #ifdef __vax
  125. #define LIM 127 /* vax fp numbers have limited range */
  126. #else
  127. #define LIM 512
  128. #endif
  129.   for (i = 1; i < LIM; i++)
  130.     {
  131.       mpz_set_ui (x, 1L);
  132.       mpz_mul_2exp (x, x, i);
  133.       y = mpz_get_d (x);
  134.       check_one ("check_low_z_one", x, y,   0, 0);
  135.       check_one ("check_low_z_one", x, -y,  1, 0);
  136.       mpz_neg (x, x);
  137.       check_one ("check_low_z_one", x, y,  -1, 0);
  138.       check_one ("check_low_z_one", x, -y,  0, 0);
  139.       mpz_neg (x, x);
  140.       mpz_sub_ui (x, x, 1);
  141.       check_one ("check_low_z_one", x, y,  -1, -1);
  142.       check_one ("check_low_z_one", x, -y,  1, -1);
  143.       mpz_neg (x, x);
  144.       check_one ("check_low_z_one", x, y,  -1, -1);
  145.       check_one ("check_low_z_one", x, -y,  1, -1);
  146.       mpz_neg (x, x);
  147.       mpz_add_ui (x, x, 2);
  148.       check_one ("check_low_z_one", x, y,   1, 1);
  149.       check_one ("check_low_z_one", x, -y,  1, 1);
  150.       mpz_neg (x, x);
  151.       check_one ("check_low_z_one", x, y,  -1, 1);
  152.       check_one ("check_low_z_one", x, -y, -1, 1);
  153.       mpz_neg (x, x);
  154.     }
  155.   mpz_clear (x);
  156. }
  157. /* Comparing 1 and 1+2^-n.  "y" is volatile to make gcc store and fetch it,
  158.    which forces it to a 64-bit double, whereas on x86 it would otherwise
  159.    remain on the float stack as an 80-bit long double.  */
  160. void
  161. check_one_2exp (void)
  162. {
  163.   double           e;
  164.   mpz_t            x;
  165.   volatile double  y;
  166.   int              i;
  167.   mpz_init (x);
  168.   e = 1.0;
  169.   for (i = 0; i < 128; i++)
  170.     {
  171.       e /= 2.0;
  172.       y = 1.0 + e;
  173.       if (y == 1.0)
  174.         break;
  175.       mpz_set_ui (x, 1L);
  176.       check_one ("check_one_2exp", x,  y, -1, -1);
  177.       check_one ("check_one_2exp", x, -y,  1, -1);
  178.       mpz_set_si (x, -1L);
  179.       check_one ("check_one_2exp", x,  y, -1, -1);
  180.       check_one ("check_one_2exp", x, -y,  1, -1);
  181.     }
  182.   mpz_clear (x);
  183. }
  184. void
  185. check_infinity (void)
  186. {
  187.   mpz_t   x;
  188.   double  y = tests_infinity_d ();
  189.   if (y == 0.0)
  190.     return;
  191.   mpz_init (x);
  192.   /* 0 cmp inf */
  193.   mpz_set_ui (x, 0L);
  194.   check_one ("check_infinity", x,  y, -1, -1);
  195.   check_one ("check_infinity", x, -y,  1, -1);
  196.   /* 123 cmp inf */
  197.   mpz_set_ui (x, 123L);
  198.   check_one ("check_infinity", x,  y, -1, -1);
  199.   check_one ("check_infinity", x, -y,  1, -1);
  200.   /* -123 cmp inf */
  201.   mpz_set_si (x, -123L);
  202.   check_one ("check_infinity", x,  y, -1, -1);
  203.   check_one ("check_infinity", x, -y,  1, -1);
  204.   /* 2^5000 cmp inf */
  205.   mpz_set_ui (x, 1L);
  206.   mpz_mul_2exp (x, x, 5000L);
  207.   check_one ("check_infinity", x,  y, -1, -1);
  208.   check_one ("check_infinity", x, -y,  1, -1);
  209.   /* -2^5000 cmp inf */
  210.   mpz_neg (x, x);
  211.   check_one ("check_infinity", x,  y, -1, -1);
  212.   check_one ("check_infinity", x, -y,  1, -1);
  213.   mpz_clear (x);
  214. }
  215. int
  216. main (int argc, char *argv[])
  217. {
  218.   tests_start ();
  219.   check_data ();
  220.   check_onebits ();
  221.   check_low_z_one ();
  222.   check_one_2exp ();
  223.   check_infinity ();
  224.   tests_end ();
  225.   exit (0);
  226. }