github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/t-double.c (about)

     1  /*
     2  
     3  Copyright 2012, 2013 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library test suite.
     6  
     7  The GNU MP Library test suite is free software; you can redistribute it
     8  and/or modify it under the terms of the GNU General Public License as
     9  published by the Free Software Foundation; either version 3 of the License,
    10  or (at your option) any later version.
    11  
    12  The GNU MP Library test suite is distributed in the hope that it will be
    13  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    15  Public License for more details.
    16  
    17  You should have received a copy of the GNU General Public License along with
    18  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    19  
    20  #include <limits.h>
    21  #include <math.h>
    22  #include <stdlib.h>
    23  #include <stdio.h>
    24  #include <string.h>
    25  
    26  #include "testutils.h"
    27  
    28  #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
    29  
    30  #define COUNT 10000
    31  
    32  static const struct
    33  {
    34    double d;
    35    const char *s;
    36  } values[] = {
    37    { 0.0, "0" },
    38    { 0.3, "0" },
    39    { -0.3, "0" },
    40    { M_PI, "3" },
    41    { M_PI*1e15, "b29430a256d21" },
    42    { -M_PI*1e15, "-b29430a256d21" },
    43    /* 17 * 2^{200} =
    44       27317946752402834684213355569799764242877450894307478200123392 */
    45    {0.2731794675240283468421335556979976424288e62,
    46      "1100000000000000000000000000000000000000000000000000" },
    47    { 0.0, NULL }
    48  };
    49  
    50  void
    51  testmain (int argc, char **argv)
    52  {
    53    unsigned i;
    54    mpz_t x;
    55  
    56    for (i = 0; values[i].s; i++)
    57      {
    58        char *s;
    59        mpz_init_set_d (x, values[i].d);
    60        s = mpz_get_str (NULL, 16, x);
    61        if (strcmp (s, values[i].s) != 0)
    62  	{
    63  	  fprintf (stderr, "mpz_set_d failed:\n"
    64  		   "d = %.20g\n"
    65  		   "s = %s\n"
    66  		   "r = %s\n",
    67  		   values[i].d, s, values[i].s);
    68  	  abort ();
    69  	}
    70        testfree (s);
    71        mpz_clear (x);
    72      }
    73  
    74    mpz_init (x);
    75  
    76    for (i = 0; i < COUNT; i++)
    77      {
    78        /* Use volatile, to avoid extended precision in floating point
    79  	 registers, e.g., on m68k and 80387. */
    80        volatile double d, f;
    81        unsigned long m;
    82        int e;
    83  
    84        mini_rrandomb (x, GMP_LIMB_BITS);
    85        m = mpz_get_ui (x);
    86        mini_urandomb (x, 8);
    87        e = mpz_get_ui (x) - 100;
    88  
    89        d = ldexp ((double) m, e);
    90        mpz_set_d (x, d);
    91        f = mpz_get_d (x);
    92        if (f != floor (d))
    93  	{
    94  	  fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n");
    95  	  goto dumperror;
    96  	}
    97        if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) >= 0))
    98  	{
    99  	  fprintf (stderr, "mpz_cmp_d (x, d) failed:\n");
   100  	  goto dumperror;
   101  	}
   102        f = d + 1.0;
   103        if (f > d && ! (mpz_cmp_d (x, f) < 0))
   104  	{
   105  	  fprintf (stderr, "mpz_cmp_d (x, f) failed:\n");
   106  	  goto dumperror;
   107  	}
   108  
   109        d = - d;
   110  
   111        mpz_set_d (x, d);
   112        f = mpz_get_d (x);
   113        if (f != ceil (d))
   114  	{
   115  	  fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n");
   116  	dumperror:
   117  	  dump ("x", x);
   118  	  fprintf (stderr, "m = %lx, e = %i\n", m, e);
   119  	  fprintf (stderr, "d = %.15g\n", d);
   120  	  fprintf (stderr, "f = %.15g\n", f);
   121  	  fprintf (stderr, "f - d = %.5g\n", f - d);
   122  	  abort ();
   123  	}
   124        if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) <= 0))
   125  	{
   126  	  fprintf (stderr, "mpz_cmp_d (x, d) failed:\n");
   127  	  goto dumperror;
   128  	}
   129        f = d - 1.0;
   130        if (f < d && ! (mpz_cmp_d (x, f) > 0))
   131  	{
   132  	  fprintf (stderr, "mpz_cmp_d (x, f) failed:\n");
   133  	  goto dumperror;
   134  	}
   135      }
   136  
   137    mpz_clear (x);
   138  }