1 /* Test file for mpfr_set_float128 and mpfr_get_float128. 2 3 Copyright 2012-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 /* Needed due to the test on MPFR_WANT_FLOAT128 */ 24 #ifdef HAVE_CONFIG_H 25 # include "config.h" 26 #endif 27 28 #ifdef MPFR_WANT_FLOAT128 29 30 #include "mpfr-test.h" 31 #include "ieee_floats.h" 32 33 static void 34 check_special (void) 35 { 36 _Float128 f; 37 mpfr_t x; 38 39 mpfr_init2 (x, 113); 40 41 #if !defined(MPFR_ERRDIVZERO) 42 /* check NaN */ 43 f = MPFR_DBL_NAN; 44 mpfr_set_float128 (x, f, MPFR_RNDN); 45 if (! mpfr_nan_p (x)) 46 { 47 printf ("Error in mpfr_set_float128(x, NaN)\n"); 48 exit (1); 49 } 50 f = mpfr_get_float128 (x, MPFR_RNDN); 51 if (! DOUBLE_ISNAN (f)) 52 { 53 printf ("Error in mpfr_get_float128(NaN)\n"); 54 printf ("got %f\n", (double) f); 55 exit (1); 56 } 57 58 /* check +Inf */ 59 f = MPFR_DBL_INFP; 60 mpfr_set_float128 (x, f, MPFR_RNDN); 61 if (! mpfr_inf_p (x) || MPFR_IS_NEG (x)) 62 { 63 printf ("Error in mpfr_set_float128(x, +Inf)\n"); 64 exit (1); 65 } 66 f = mpfr_get_float128 (x, MPFR_RNDN); 67 if (f != MPFR_DBL_INFP) 68 { 69 printf ("Error in mpfr_get_float128(+Inf)\n"); 70 exit (1); 71 } 72 73 /* check -Inf */ 74 f = MPFR_DBL_INFM; 75 mpfr_set_float128 (x, f, MPFR_RNDN); 76 if (! mpfr_inf_p (x) || MPFR_IS_POS (x)) 77 { 78 printf ("Error in mpfr_set_float128(x, -Inf)\n"); 79 exit (1); 80 } 81 f = mpfr_get_float128 (x, MPFR_RNDN); 82 if (f != MPFR_DBL_INFM) 83 { 84 printf ("Error in mpfr_get_float128(-Inf)\n"); 85 exit (1); 86 } 87 #endif 88 89 /* check +0 */ 90 f = 0.0; 91 mpfr_set_float128 (x, f, MPFR_RNDN); 92 if (! mpfr_zero_p (x) || MPFR_IS_NEG (x)) 93 { 94 printf ("Error in mpfr_set_float128(x, +0)\n"); 95 exit (1); 96 } 97 f = mpfr_get_float128 (x, MPFR_RNDN); 98 if (f != 0.0) /* the sign is not checked */ 99 { 100 printf ("Error in mpfr_get_float128(+0.0)\n"); 101 exit (1); 102 } 103 #if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ) 104 if (1 / f != MPFR_DBL_INFP) /* check the sign */ 105 { 106 printf ("Error in mpfr_get_float128(+0.0)\n"); 107 exit (1); 108 } 109 #endif 110 111 /* check -0 */ 112 f = -0.0; 113 mpfr_set_float128 (x, f, MPFR_RNDN); 114 if (! mpfr_zero_p (x)) 115 { 116 printf ("Error in mpfr_set_float128(x, -0)\n"); 117 exit (1); 118 } 119 #if defined(HAVE_SIGNEDZ) 120 if (MPFR_IS_POS (x)) 121 { 122 printf ("Error in mpfr_set_float128(x, -0)\n"); 123 exit (1); 124 } 125 #endif 126 f = mpfr_get_float128 (x, MPFR_RNDN); 127 if (f != -0.0) /* the sign is not checked */ 128 { 129 printf ("Error in mpfr_get_float128(-0.0)\n"); 130 exit (1); 131 } 132 #if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ) 133 if (1 / f != MPFR_DBL_INFM) /* check the sign */ 134 { 135 printf ("Error in mpfr_get_float128(-0.0)\n"); 136 exit (1); 137 } 138 #endif 139 140 mpfr_clear (x); 141 } 142 143 static void 144 check_large (void) 145 { 146 mpfr_exp_t emin, emax; 147 _Float128 f, e; 148 int i; 149 mpfr_t x, y; 150 int r; 151 int red; 152 153 emin = mpfr_get_emin (); 154 emax = mpfr_get_emax (); 155 156 mpfr_init2 (x, 113); 157 mpfr_init2 (y, 113); 158 159 /* check with the largest float128 number 2^16384*(1-2^(-113)) */ 160 for (f = 1.0, i = 0; i < 113; i++) 161 f = f + f; 162 f = f - (_Float128) 1.0; 163 mpfr_set_ui (y, 1, MPFR_RNDN); 164 mpfr_mul_2ui (y, y, 113, MPFR_RNDN); 165 mpfr_sub_ui (y, y, 1, MPFR_RNDN); 166 for (i = 113; i < 16384; i++) 167 { 168 RND_LOOP (r) 169 { 170 mpfr_set_float128 (x, f, (mpfr_rnd_t) r); 171 if (! mpfr_equal_p (x, y)) 172 { 173 printf ("mpfr_set_float128 failed for 2^%d*(1-2^(-113)) rnd=%s\n", 174 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 175 printf ("got "); 176 mpfr_dump (x); 177 exit (1); 178 } 179 for (red = 0; red < 2; red++) 180 { 181 if (red) 182 { 183 mpfr_exp_t ex; 184 185 if (MPFR_IS_SINGULAR (x)) 186 break; 187 ex = MPFR_GET_EXP (x); 188 set_emin (ex); 189 set_emax (ex); 190 } 191 e = mpfr_get_float128 (x, (mpfr_rnd_t) r); 192 set_emin (emin); 193 set_emax (emax); 194 if (e != f) 195 { 196 printf ("mpfr_get_float128 failed for 2^%d*(1-2^(-113))" 197 " rnd=%s%s\n", 198 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r), 199 red ? ", reduced exponent range" : ""); 200 exit (1); 201 } 202 } 203 } 204 205 /* check with opposite number */ 206 f = -f; 207 mpfr_neg (y, y, MPFR_RNDN); 208 RND_LOOP (r) 209 { 210 mpfr_set_float128 (x, f, (mpfr_rnd_t) r); 211 if (! mpfr_equal_p (x, y)) 212 { 213 printf ("mpfr_set_float128 failed for -2^%d*(1-2^(-113)) rnd=%s\n", 214 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 215 printf ("got "); 216 mpfr_dump (x); 217 exit (1); 218 } 219 e = mpfr_get_float128 (x, (mpfr_rnd_t) r); 220 if (e != f) 221 { 222 printf ("mpfr_get_float128 failed for -2^%d*(1-2^(-113)) rnd=%s\n", 223 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 224 exit (1); 225 } 226 } 227 228 f = -f; 229 mpfr_neg (y, y, MPFR_RNDN); 230 f = f + f; 231 mpfr_add (y, y, y, MPFR_RNDN); 232 } 233 234 mpfr_clear (x); 235 mpfr_clear (y); 236 } 237 238 static void 239 check_small (void) 240 { 241 int t[5] = { 1, 2, 17, 111, 112 }; 242 mpfr_exp_t emin; 243 _Float128 e, f; 244 int i, j, neg, inex, r; 245 mpfr_t w, x, y, z; 246 247 emin = mpfr_get_emin (); 248 249 mpfr_inits2 (113, w, x, y, z, (mpfr_ptr) 0); 250 251 f = 1.0; 252 mpfr_set_ui (y, 1, MPFR_RNDN); 253 for (i = 0; i > -16500; i--) 254 { 255 for (j = 0; j < 5; j++) 256 { 257 mpfr_div_2ui (z, y, t[j], MPFR_RNDN); 258 inex = mpfr_add (z, z, y, MPFR_RNDN); 259 MPFR_ASSERTN (inex == 0); 260 /* z = y (1 + 2^(-t[j]) */ 261 for (neg = 0; neg < 2; neg++) 262 { 263 RND_LOOP_NO_RNDF (r) 264 { 265 if (j == 0 && f != 0) 266 { 267 /* This test does not depend on j. */ 268 mpfr_set_float128 (x, f, (mpfr_rnd_t) r); 269 if (! mpfr_equal_p (x, y)) 270 { 271 printf ("mpfr_set_float128 failed for " 272 "%c2^(%d) rnd=%s\n", neg ? '-' : '+', i, 273 mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 274 printf ("got "); 275 mpfr_dump (x); 276 exit (1); 277 } 278 e = mpfr_get_float128 (x, (mpfr_rnd_t) r); 279 if (e != f) 280 { 281 printf ("mpfr_get_float128 failed for " 282 "%c2^(%d) rnd=%s\n", neg ? '-' : '+', i, 283 mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 284 exit (1); 285 } 286 } 287 if (i < -16378) 288 { 289 /* Subnormals or close to subnormals... 290 Here we mainly test mpfr_get_float128. */ 291 e = mpfr_get_float128 (z, (mpfr_rnd_t) r); 292 mpfr_set_float128 (x, e, MPFR_RNDN); /* exact */ 293 inex = mpfr_set (w, z, MPFR_RNDN); 294 MPFR_ASSERTN (inex == 0); 295 set_emin (-16493); 296 inex = mpfr_check_range (w, 0, (mpfr_rnd_t) r); 297 mpfr_subnormalize (w, inex, (mpfr_rnd_t) r); 298 set_emin (emin); 299 if (! mpfr_equal_p (x, w)) 300 { 301 printf ("mpfr_get_float128 failed for " 302 "%c(2^(%d))(1+2^(-%d)) rnd=%s\n", 303 neg ? '-' : '+', i, t[j], 304 mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 305 printf ("expected "); 306 mpfr_dump (w); 307 printf ("got "); 308 mpfr_dump (x); 309 exit (1); 310 } 311 } 312 } 313 f = -f; 314 mpfr_neg (y, y, MPFR_RNDN); 315 mpfr_neg (z, z, MPFR_RNDN); 316 } 317 } 318 f = 0.5 * f; 319 mpfr_div_2ui (y, y, 1, MPFR_RNDN); 320 } 321 322 mpfr_clears (w, x, y, z, (mpfr_ptr) 0); 323 } 324 325 int 326 main (int argc, char *argv[]) 327 { 328 tests_start_mpfr (); 329 330 check_special (); 331 332 check_large (); 333 334 check_small (); 335 336 tests_end_mpfr (); 337 338 return 0; 339 } 340 341 #else /* MPFR_WANT_FLOAT128 */ 342 343 /* dummy main to say this test is ignored */ 344 int 345 main (void) 346 { 347 return 77; 348 } 349 350 #endif /* MPFR_WANT_FLOAT128 */ 351