xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset_d.c (revision ba125506a622fe649968631a56eba5d42ff57863)
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
main(int argc,char * argv[])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 }
221