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