xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset_d.c (revision a4ddc2c8fb9af816efe3b1c375a5530aef0e89e9)
1 /* Test file for mpfr_set_d and mpfr_get_d.
2 
3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao 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 http://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 <stdio.h>
24 #include <stdlib.h>
25 #include <float.h>
26 
27 #include "mpfr-test.h"
28 
29 int
30 main (int argc, char *argv[])
31 {
32   mpfr_t x, y, z;
33   unsigned long k, n;
34   volatile double d;
35   double dd;
36 
37   tests_start_mpfr ();
38   mpfr_test_init ();
39 
40 #ifndef MPFR_DOUBLE_SPEC
41   printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n"
42           "that you do not have a conforming C implementation and problems\n"
43           "may occur with conversions between MPFR numbers and standard\n"
44           "floating-point types. Please contact the MPFR team.\n");
45 #elif MPFR_DOUBLE_SPEC == 0
46   /*
47   printf ("The type 'double' of your C implementation does not seem to\n"
48           "correspond to the IEEE-754 double precision. Though code has\n"
49           "been written to support such implementations, tests have been\n"
50           "done only on IEEE-754 double-precision implementations and\n"
51           "conversions between MPFR numbers and standard floating-point\n"
52           "types may be inaccurate. You may wish to contact the MPFR team\n"
53           "for further testing.\n");
54   */
55   printf ("The type 'double' of your C implementation does not seem to\n"
56           "correspond to the IEEE-754 double precision. Such particular\n"
57           "implementations are not supported yet, and conversions between\n"
58           "MPFR numbers and standard floating-point types may be very\n"
59           "inaccurate.\n");
60   printf ("FLT_RADIX    = %ld\n", (long) FLT_RADIX);
61   printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG);
62   printf ("DBL_MIN_EXP  = %ld\n", (long) DBL_MIN_EXP);
63   printf ("DBL_MAX_EXP  = %ld\n", (long) DBL_MAX_EXP);
64 #endif
65 
66   mpfr_init (x);
67 
68   mpfr_set_nan (x);
69   d = mpfr_get_d (x, MPFR_RNDN);
70   if (! DOUBLE_ISNAN (d))
71     {
72       printf ("ERROR for NAN (1)\n");
73 #ifdef MPFR_NANISNAN
74       printf ("The reason is that NAN == NAN. Please look at the configure "
75               "output\nand Section \"In case of problem\" of the INSTALL "
76               "file.\n");
77 #endif
78       exit (1);
79     }
80   mpfr_set_ui (x, 0, MPFR_RNDN);
81   mpfr_set_d (x, d, MPFR_RNDN);
82   if (! mpfr_nan_p (x))
83     {
84       printf ("ERROR for NAN (2)\n");
85 #ifdef MPFR_NANISNAN
86       printf ("The reason is that NAN == NAN. Please look at the configure "
87               "output\nand Section \"In case of problem\" of the INSTALL "
88               "file.\n");
89 #endif
90       exit (1);
91     }
92 
93   d = 0.0;
94   mpfr_set_d (x, d, MPFR_RNDN);
95   MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
96   d = -d;
97   mpfr_set_d (x, d, MPFR_RNDN);
98   if (mpfr_cmp_ui (x, 0) != 0 || MPFR_IS_POS(x))
99     {
100       printf ("Error in mpfr_set_d on -0\n");
101       exit (1);
102     }
103 
104   mpfr_set_inf (x, 1);
105   d = mpfr_get_d (x, MPFR_RNDN);
106   mpfr_set_ui (x, 0, MPFR_RNDN);
107   mpfr_set_d (x, d, MPFR_RNDN);
108   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
109 
110   mpfr_set_inf (x, -1);
111   d = mpfr_get_d (x, MPFR_RNDN);
112   mpfr_set_ui (x, 0, MPFR_RNDN);
113   mpfr_set_d (x, d, MPFR_RNDN);
114   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
115 
116   mpfr_set_prec (x, 2);
117 
118   /* checks that denormalized are not flushed to zero */
119   d = DBL_MIN; /* 2^(-1022) */
120   for (n=0; n<52; n++, d /= 2.0)
121     if (d != 0.0) /* should be 2^(-1022-n) */
122       {
123         mpfr_set_d (x, d, MPFR_RNDN);
124         if (mpfr_cmp_ui_2exp (x, 1, -1022-n))
125           {
126             printf ("Wrong result for d=2^(%ld), ", -1022-n);
127             printf ("got ");
128             mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN);
129             printf ("\n");
130             mpfr_print_binary (x);
131             puts ("");
132             exit (1);
133           }
134       }
135 
136    /* checks that rounds to nearest sets the last
137      bit to zero in case of equal distance */
138    mpfr_set_d (x, 5.0, MPFR_RNDN);
139    if (mpfr_cmp_ui (x, 4))
140      {
141        printf ("Error in tset_d: expected 4.0, got ");
142        mpfr_print_binary (x); putchar('\n');
143        exit (1);
144      }
145    mpfr_set_d (x, -5.0, MPFR_RNDN);
146    if (mpfr_cmp_si (x, -4))
147      {
148        printf ("Error in tset_d: expected -4.0, got ");
149        mpfr_print_binary (x); putchar('\n');
150        exit (1);
151      }
152 
153    mpfr_set_d (x, 9.84891017624509146344e-01, MPFR_RNDU);
154    if (mpfr_cmp_ui (x, 1))
155      {
156        printf ("Error in tset_d: expected 1.0, got ");
157        mpfr_print_binary (x); putchar('\n');
158        exit (1);
159      }
160 
161   mpfr_init2 (z, 32);
162   mpfr_set_d (z, 1.0, (mpfr_rnd_t) 0);
163   if (mpfr_cmp_ui (z, 1))
164     {
165       mpfr_print_binary (z); puts ("");
166       printf ("Error: 1.0 != 1.0\n");
167       exit (1);
168     }
169   mpfr_set_prec (x, 53);
170   mpfr_init2 (y, 53);
171   mpfr_set_d (x, d=-1.08007920352320089721e+150, (mpfr_rnd_t) 0);
172   if (mpfr_get_d1 (x) != d)
173     {
174       mpfr_print_binary (x); puts ("");
175       printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
176               d, mpfr_get_d1 (x));
177       exit (1);
178     }
179 
180   mpfr_set_d (x, 8.06294740693074521573e-310, (mpfr_rnd_t) 0);
181   d = -6.72658901114033715233e-165;
182   mpfr_set_d (x, d, (mpfr_rnd_t) 0);
183   if (d != mpfr_get_d1 (x))
184     {
185       mpfr_print_binary (x);
186       puts ("");
187       printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
188               d, mpfr_get_d1 (x));
189       exit (1);
190     }
191 
192   n = (argc==1) ? 500000 : atoi(argv[1]);
193   for (k = 1; k <= n; k++)
194     {
195       do
196         {
197           d = DBL_RAND ();
198         }
199 #ifdef HAVE_DENORMS
200       while (0);
201 #else
202       while (ABS(d) < DBL_MIN);
203 #endif
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_print_binary (x);
210           puts ("");
211           exit (1);
212         }
213     }
214 
215   mpfr_clear (x);
216   mpfr_clear (y);
217   mpfr_clear (z);
218 
219   tests_end_mpfr ();
220   return 0;
221 }
222