(root)/
mpfr-4.2.1/
tests/
tset_d.c
       1  /* Test file for mpfr_set_d and mpfr_get_d.
       2  
       3  Copyright 1999-2023 Free Software Foundation, Inc.
       4  Contributed by the AriC and Caramba projects, INRIA.
       5  
       6  This file is part of the GNU MPFR Library.
       7  
       8  The GNU MPFR Library is free software; you can redistribute it and/or modify
       9  it under the terms of the GNU Lesser General Public License as published by
      10  the Free Software Foundation; either version 3 of the License, or (at your
      11  option) any later version.
      12  
      13  The GNU MPFR Library is distributed in the hope that it will be useful, but
      14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      15  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
      16  License for more details.
      17  
      18  You should have received a copy of the GNU Lesser General Public License
      19  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
      20  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
      21  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
      22  
      23  #include <float.h>
      24  
      25  #include "mpfr-test.h"
      26  
      27  int
      28  main (int argc, char *argv[])
      29  {
      30    mpfr_t x, y, z;
      31    unsigned long k, n;
      32    volatile double d;
      33    double dd;
      34  
      35    tests_start_mpfr ();
      36    mpfr_test_init ();
      37  
      38  #ifndef MPFR_DOUBLE_SPEC
      39    printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n"
      40            "that you do not have a conforming C implementation and problems\n"
      41            "may occur with conversions between MPFR numbers and standard\n"
      42            "floating-point types. Please contact the MPFR team.\n");
      43  #elif MPFR_DOUBLE_SPEC == 0
      44    /*
      45    printf ("The type 'double' of your C implementation does not seem to\n"
      46            "correspond to the IEEE-754 double precision. Though code has\n"
      47            "been written to support such implementations, tests have been\n"
      48            "done only on IEEE-754 double-precision implementations and\n"
      49            "conversions between MPFR numbers and standard floating-point\n"
      50            "types may be inaccurate. You may wish to contact the MPFR team\n"
      51            "for further testing.\n");
      52    */
      53    printf ("The type 'double' of your C implementation does not seem to\n"
      54            "correspond to the IEEE-754 double precision. Such particular\n"
      55            "implementations are not supported yet, and conversions between\n"
      56            "MPFR numbers and standard floating-point types may be very\n"
      57            "inaccurate.\n");
      58    printf ("FLT_RADIX    = %ld\n", (long) FLT_RADIX);
      59    printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG);
      60    printf ("DBL_MIN_EXP  = %ld\n", (long) DBL_MIN_EXP);
      61    printf ("DBL_MAX_EXP  = %ld\n", (long) DBL_MAX_EXP);
      62  #endif
      63  
      64    mpfr_init (x);
      65  
      66  #if !defined(MPFR_ERRDIVZERO)
      67    mpfr_set_nan (x);
      68    d = mpfr_get_d (x, MPFR_RNDN);
      69    if (! DOUBLE_ISNAN (d))
      70      {
      71        printf ("ERROR for NAN (1)\n");
      72  #ifdef MPFR_NANISNAN
      73        printf ("The reason is that NAN == NAN. Please look at the configure "
      74                "output\nand Section \"In case of problem\" of the INSTALL "
      75                "file.\n");
      76  #endif
      77        exit (1);
      78      }
      79    mpfr_set_ui (x, 0, MPFR_RNDN);
      80    mpfr_set_d (x, d, MPFR_RNDN);
      81    if (! mpfr_nan_p (x))
      82      {
      83        printf ("ERROR for NAN (2)\n");
      84  #ifdef MPFR_NANISNAN
      85        printf ("The reason is that NAN == NAN. Please look at the configure "
      86                "output\nand Section \"In case of problem\" of the INSTALL "
      87                "file.\n");
      88  #endif
      89        exit (1);
      90      }
      91  #endif  /* MPFR_ERRDIVZERO */
      92  
      93  #ifdef HAVE_SIGNEDZ
      94    d = 0.0;
      95    mpfr_set_d (x, d, MPFR_RNDN);
      96    MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
      97    d = -d;
      98    mpfr_set_d (x, d, MPFR_RNDN);
      99    if (mpfr_cmp_ui (x, 0) != 0 || MPFR_IS_POS(x))
     100      {
     101        printf ("Error in mpfr_set_d on -0\n");
     102        printf ("d = %g, x = ", d);
     103        mpfr_dump (x);
     104        exit (1);
     105      }
     106  #endif  /* HAVE_SIGNEDZ */
     107  
     108  #if !defined(MPFR_ERRDIVZERO)
     109    mpfr_set_inf (x, 1);
     110    d = mpfr_get_d (x, MPFR_RNDN);
     111    mpfr_set_ui (x, 0, MPFR_RNDN);
     112    mpfr_set_d (x, d, MPFR_RNDN);
     113    MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
     114  
     115    mpfr_set_inf (x, -1);
     116    d = mpfr_get_d (x, MPFR_RNDN);
     117    mpfr_set_ui (x, 0, MPFR_RNDN);
     118    mpfr_set_d (x, d, MPFR_RNDN);
     119    MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
     120  #endif  /* MPFR_ERRDIVZERO */
     121  
     122    mpfr_set_prec (x, 2);
     123  
     124    /* checks that subnormals are not flushed to zero */
     125    d = DBL_MIN; /* 2^(-1022) */
     126    for (n = 0; n < 53; n++, d /= 2.0)
     127      if (d != 0.0) /* should be 2^(-1022-n) */
     128        {
     129          mpfr_set_d (x, d, MPFR_RNDN);
     130          if (mpfr_cmp_ui_2exp (x, 1, -1022-n))
     131            {
     132              printf ("Wrong result for d=2^(%ld), ", -1022-n);
     133              printf ("got ");
     134              mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN);
     135              printf ("\n");
     136              mpfr_dump (x);
     137              exit (1);
     138            }
     139        }
     140  
     141     /* checks that rounds to nearest sets the last
     142       bit to zero in case of equal distance */
     143     mpfr_set_d (x, 5.0, MPFR_RNDN);
     144     if (mpfr_cmp_ui (x, 4))
     145       {
     146         printf ("Error in tset_d: expected 4.0, got ");
     147         mpfr_dump (x);
     148         exit (1);
     149       }
     150     mpfr_set_d (x, -5.0, MPFR_RNDN);
     151     if (mpfr_cmp_si (x, -4))
     152       {
     153         printf ("Error in tset_d: expected -4.0, got ");
     154         mpfr_dump (x);
     155         exit (1);
     156       }
     157  
     158     mpfr_set_d (x, 9.84891017624509146344e-01, MPFR_RNDU);
     159     if (mpfr_cmp_ui (x, 1))
     160       {
     161         printf ("Error in tset_d: expected 1.0, got ");
     162         mpfr_dump (x);
     163         exit (1);
     164       }
     165  
     166    mpfr_init2 (z, 32);
     167    mpfr_set_d (z, 1.0, (mpfr_rnd_t) 0);
     168    if (mpfr_cmp_ui (z, 1))
     169      {
     170        mpfr_dump (z);
     171        printf ("Error: 1.0 != 1.0\n");
     172        exit (1);
     173      }
     174    mpfr_set_prec (x, 53);
     175    mpfr_init2 (y, 53);
     176    mpfr_set_d (x, d=-1.08007920352320089721e+150, (mpfr_rnd_t) 0);
     177    if (mpfr_get_d1 (x) != d)
     178      {
     179        mpfr_dump (x);
     180        printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
     181                d, mpfr_get_d1 (x));
     182        exit (1);
     183      }
     184  
     185    mpfr_set_d (x, 8.06294740693074521573e-310, (mpfr_rnd_t) 0);
     186    d = -6.72658901114033715233e-165;
     187    mpfr_set_d (x, d, (mpfr_rnd_t) 0);
     188    if (d != mpfr_get_d1 (x))
     189      {
     190        mpfr_dump (x);
     191        printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
     192                d, mpfr_get_d1 (x));
     193        exit (1);
     194      }
     195  
     196    n = argc == 1 ? 500000 : atoi (argv[1]);
     197    for (k = 1; k <= n; k++)
     198      {
     199        do
     200          {
     201            d = DBL_RAND ();
     202          }
     203        while (ABS(d) < DBL_MIN);
     204        mpfr_set_d (x, d, (mpfr_rnd_t) 0);
     205        dd = mpfr_get_d1 (x);
     206        if (d != dd && !(Isnan(d) && Isnan(dd)))
     207          {
     208            printf ("Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d1 (x));
     209            mpfr_dump (x);
     210            exit (1);
     211          }
     212      }
     213  
     214    mpfr_clear (x);
     215    mpfr_clear (y);
     216    mpfr_clear (z);
     217  
     218    tests_end_mpfr ();
     219    return 0;
     220  }