1 /* Test file for mpfr_set. 2 3 Copyright 2001-2020 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 "mpfr-test.h" 24 25 static int error; 26 27 #define PRINT_ERROR_IF(condition, text) \ 28 do { \ 29 if (condition) \ 30 { \ 31 printf ("%s", text); \ 32 error = 1; \ 33 } \ 34 } while (0) 35 36 37 /* Maybe better create its own test file? */ 38 static void 39 check_neg_special (void) 40 { 41 mpfr_t x, y; 42 int inexact; 43 int s1, s2, s3; 44 45 mpfr_inits2 (53, x, y, (mpfr_ptr) 0); 46 47 MPFR_SET_NAN (x); 48 s1 = mpfr_signbit (x) != 0; 49 50 mpfr_clear_nanflag (); 51 inexact = mpfr_neg (y, x, MPFR_RNDN); 52 s2 = mpfr_signbit (y) != 0; 53 PRINT_ERROR_IF (!mpfr_nanflag_p (), 54 "ERROR: neg (NaN) doesn't set Nan flag (1).\n"); 55 PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0, 56 "ERROR: neg (NaN) failed to set variable to NaN (1).\n"); 57 PRINT_ERROR_IF (s1 == s2, 58 "ERROR: neg (NaN) doesn't correctly flip sign bit (1).\n"); 59 60 mpfr_clear_nanflag (); 61 inexact = mpfr_neg (x, x, MPFR_RNDN); 62 s2 = mpfr_signbit (x) != 0; 63 PRINT_ERROR_IF (!mpfr_nanflag_p (), 64 "ERROR: neg (NaN) doesn't set Nan flag (2).\n"); 65 PRINT_ERROR_IF (!mpfr_nan_p (x) || inexact != 0, 66 "ERROR: neg (NaN) failed to set variable to NaN (2).\n"); 67 /* check following "bug" is fixed: 68 https://sympa.inria.fr/sympa/arc/mpfr/2017-11/msg00003.html */ 69 PRINT_ERROR_IF (s1 == s2, 70 "ERROR: neg (NaN) doesn't correctly flip sign bit (2).\n"); 71 72 mpfr_clear_nanflag (); 73 inexact = mpfr_neg (y, x, MPFR_RNDN); 74 s3 = mpfr_signbit (y) != 0; 75 PRINT_ERROR_IF (!mpfr_nanflag_p (), 76 "ERROR: neg (NaN) doesn't set Nan flag (3).\n"); 77 PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0, 78 "ERROR: neg (NaN) failed to set variable to NaN (3).\n"); 79 PRINT_ERROR_IF (s2 == s3, 80 "ERROR: neg (NaN) doesn't correctly flip sign bit (3).\n"); 81 82 mpfr_clear_nanflag (); 83 inexact = mpfr_neg (x, x, MPFR_RNDN); 84 s3 = mpfr_signbit (x) != 0; 85 PRINT_ERROR_IF (!mpfr_nanflag_p (), 86 "ERROR: neg (NaN) doesn't set Nan flag (4).\n"); 87 PRINT_ERROR_IF (!mpfr_nan_p (x) || inexact != 0, 88 "ERROR: neg (NaN) failed to set variable to NaN (4).\n"); 89 PRINT_ERROR_IF (s2 == s3, 90 "ERROR: neg (NaN) doesn't correctly flip sign bit (4).\n"); 91 92 mpfr_clears (x, y, (mpfr_ptr) 0); 93 } 94 95 static void 96 check_special (void) 97 { 98 mpfr_t x, y; 99 int inexact; 100 int s1, s2; 101 102 mpfr_inits2 (53, x, y, (mpfr_ptr) 0); 103 104 mpfr_set_inf (x, 1); 105 PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0, 106 "ERROR: mpfr_set_inf failed to set variable to +inf [1].\n"); 107 mpfr_set_inf (x, INT_MAX); 108 PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0, 109 "ERROR: mpfr_set_inf failed to set variable to +inf [2].\n"); 110 mpfr_set_inf (x, 0); 111 PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0, 112 "ERROR: mpfr_set_inf failed to set variable to +inf [3].\n"); 113 inexact = mpfr_set (y, x, MPFR_RNDN); 114 PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || inexact != 0, 115 "ERROR: mpfr_set failed to set variable to +infinity.\n"); 116 117 inexact = mpfr_set_ui (y, 0, MPFR_RNDN); 118 PRINT_ERROR_IF (MPFR_NOTZERO (y) || MPFR_IS_NEG (y) || inexact != 0, 119 "ERROR: mpfr_set_ui failed to set variable to +0.\n"); 120 121 mpfr_set_inf (x, -1); 122 PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) > 0, 123 "ERROR: mpfr_set_inf failed to set variable to -inf [1].\n"); 124 mpfr_set_inf (x, INT_MIN); 125 PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) > 0, 126 "ERROR: mpfr_set_inf failed to set variable to -inf [2].\n"); 127 inexact = mpfr_set (y, x, MPFR_RNDN); 128 PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) > 0 || inexact != 0, 129 "ERROR: mpfr_set failed to set variable to -infinity.\n"); 130 131 mpfr_set_zero (x, 1); 132 PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_NEG (x), 133 "ERROR: mpfr_set_zero failed to set variable to +0 [1].\n"); 134 mpfr_set_zero (x, INT_MAX); 135 PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_NEG (x), 136 "ERROR: mpfr_set_zero failed to set variable to +0 [2].\n"); 137 mpfr_set_zero (x, 0); 138 PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_NEG (x), 139 "ERROR: mpfr_set_zero failed to set variable to +0 [3].\n"); 140 inexact = mpfr_set (y, x, MPFR_RNDN); 141 PRINT_ERROR_IF (MPFR_NOTZERO (y) || MPFR_IS_NEG (y) || inexact != 0, 142 "ERROR: mpfr_set failed to set variable to +0.\n"); 143 144 mpfr_set_zero (x, -1); 145 PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_POS (x), 146 "ERROR: mpfr_set_zero failed to set variable to -0 [1].\n"); 147 mpfr_set_zero (x, INT_MIN); 148 PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_POS (x), 149 "ERROR: mpfr_set_zero failed to set variable to -0 [2].\n"); 150 inexact = mpfr_set (y, x, MPFR_RNDN); 151 PRINT_ERROR_IF (MPFR_NOTZERO (y) || MPFR_IS_POS (y) || inexact != 0, 152 "ERROR: mpfr_set failed to set variable to -0.\n"); 153 154 /* NaN tests */ 155 156 mpfr_set_nan (x); 157 PRINT_ERROR_IF (!mpfr_nan_p (x), 158 "ERROR: mpfr_set_nan failed to set variable to NaN.\n"); 159 s1 = mpfr_signbit (x) != 0; 160 161 mpfr_clear_nanflag (); 162 inexact = mpfr_set (y, x, MPFR_RNDN); 163 s2 = mpfr_signbit (y) != 0; 164 PRINT_ERROR_IF (!mpfr_nanflag_p (), 165 "ERROR: mpfr_set doesn't set Nan flag (1).\n"); 166 PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0, 167 "ERROR: mpfr_set failed to set variable to NaN (1).\n"); 168 PRINT_ERROR_IF (s1 != s2, 169 "ERROR: mpfr_set doesn't preserve the sign bit (1).\n"); 170 171 mpfr_clear_nanflag (); 172 inexact = mpfr_set (x, x, MPFR_RNDN); 173 s2 = mpfr_signbit (x) != 0; 174 PRINT_ERROR_IF (!mpfr_nanflag_p (), 175 "ERROR: mpfr_set doesn't set Nan flag (2).\n"); 176 PRINT_ERROR_IF (!mpfr_nan_p (x) || inexact != 0, 177 "ERROR: mpfr_set failed to set variable to NaN (2).\n"); 178 PRINT_ERROR_IF (s1 != s2, 179 "ERROR: mpfr_set doesn't preserve the sign bit (2).\n"); 180 181 MPFR_CHANGE_SIGN (x); 182 s1 = !s1; 183 184 mpfr_clear_nanflag (); 185 inexact = mpfr_set (y, x, MPFR_RNDN); 186 s2 = mpfr_signbit (y) != 0; 187 PRINT_ERROR_IF (!mpfr_nanflag_p (), 188 "ERROR: mpfr_set doesn't set Nan flag (3).\n"); 189 PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0, 190 "ERROR: mpfr_set failed to set variable to NaN (3).\n"); 191 PRINT_ERROR_IF (s1 != s2, 192 "ERROR: mpfr_set doesn't preserve the sign bit (3).\n"); 193 194 mpfr_clear_nanflag (); 195 inexact = mpfr_set (x, x, MPFR_RNDN); 196 s2 = mpfr_signbit (x) != 0; 197 PRINT_ERROR_IF (!mpfr_nanflag_p (), 198 "ERROR: mpfr_set doesn't set Nan flag (4).\n"); 199 PRINT_ERROR_IF (!mpfr_nan_p (x) || inexact != 0, 200 "ERROR: mpfr_set failed to set variable to NaN (4).\n"); 201 PRINT_ERROR_IF (s1 != s2, 202 "ERROR: mpfr_set doesn't preserve the sign bit (4).\n"); 203 204 mpfr_clears (x, y, (mpfr_ptr) 0); 205 } 206 207 static void 208 check_ternary_value (void) 209 { 210 int p, q, rnd; 211 int inexact, cmp; 212 mpfr_t x, y; 213 214 mpfr_init (x); 215 mpfr_init (y); 216 for (p=2; p<500; p++) 217 { 218 mpfr_set_prec (x, p); 219 mpfr_urandomb (x, RANDS); 220 if (randlimb () % 2) 221 mpfr_neg (x, x, MPFR_RNDN); 222 for (q=2; q<2*p; q++) 223 { 224 mpfr_set_prec (y, q); 225 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 226 { 227 if (rnd == MPFR_RNDF) /* the test below makes no sense */ 228 continue; 229 inexact = mpfr_set (y, x, (mpfr_rnd_t) rnd); 230 cmp = mpfr_cmp (y, x); 231 if (((inexact == 0) && (cmp != 0)) || 232 ((inexact > 0) && (cmp <= 0)) || 233 ((inexact < 0) && (cmp >= 0))) 234 { 235 printf ("Wrong ternary value in mpfr_set for %s: expected" 236 " %d, got %d\n", 237 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), cmp, 238 inexact); 239 exit (1); 240 } 241 /* Test mpfr_set function too */ 242 inexact = (mpfr_set) (y, x, (mpfr_rnd_t) rnd); 243 cmp = mpfr_cmp (y, x); 244 if (((inexact == 0) && (cmp != 0)) || 245 ((inexact > 0) && (cmp <= 0)) || 246 ((inexact < 0) && (cmp >= 0))) 247 { 248 printf ("Wrong ternary value in mpfr_set(2): expected %d," 249 " got %d\n", cmp, inexact); 250 exit (1); 251 } 252 } 253 } 254 } 255 mpfr_clear (x); 256 mpfr_clear (y); 257 } 258 259 static void 260 test_set_1_2 (void) 261 { 262 mpfr_t u, v, zz, z; 263 int inex; 264 265 /* (8,16)-bit test */ 266 mpfr_inits2 (16, u, v, zz, (mpfr_ptr) 0); 267 mpfr_init2 (z, 8); 268 mpfr_set_str_binary (u, "0.1100001100011010E-1"); 269 mpfr_set_str_binary (v, "0.1100010101110010E0"); 270 /* u + v = 1.0010011011111111 */ 271 inex = mpfr_add (zz, u, v, MPFR_RNDN); 272 MPFR_ASSERTN(inex > 0); 273 mpfr_set_str_binary (u, "1.001001110000000"); 274 MPFR_ASSERTN(mpfr_equal_p (zz, u)); 275 inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex); 276 /* we should have z = 1.0010011 and inex < 0 */ 277 MPFR_ASSERTN(inex < 0); 278 mpfr_set_str_binary (u, "1.0010011"); 279 MPFR_ASSERTN(mpfr_equal_p (z, u)); 280 mpfr_clears (u, v, zz, z, (mpfr_ptr) 0); 281 282 /* (16,32)-bit test: 283 * take for v a random 32-bit number in [1/2,1), here 2859611790/2^32 284 * take for z a random 16-bit number in [1,2), less than 2*v, 285 with last bit 0, here we take z = 40900/2^15 286 * take u = z-v-1/2^16-1/2^32 */ 287 mpfr_inits2 (32, u, v, zz, (mpfr_ptr) 0); 288 mpfr_init2 (z, 16); 289 mpfr_set_str_binary (u, "0.10010101000101001100100101110001"); 290 mpfr_set_str_binary (v, "0.10101010011100100011011010001110"); 291 /* u + v = 1.00111111100001101111111111111111 */ 292 inex = mpfr_add (zz, u, v, MPFR_RNDN); 293 MPFR_ASSERTN(inex > 0); 294 mpfr_set_str_binary (u, "1.0011111110000111"); 295 MPFR_ASSERTN(mpfr_equal_p (zz, u)); 296 inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex); 297 /* we should have z = 1.001111111000011 and inex < 0 */ 298 MPFR_ASSERTN(inex < 0); 299 mpfr_set_str_binary (u, "1.001111111000011"); 300 MPFR_ASSERTN(mpfr_equal_p (z, u)); 301 mpfr_clears (u, v, zz, z, (mpfr_ptr) 0); 302 303 /* (32,64)-bit test: 304 * take for v a random 64-bit number in [1/2,1), 305 here v = 13687985014345662879/2^64 306 * take for z a random 32-bit number in [1,2), less than 2*v, 307 with last bit 0, here we take z = 2871078774/2^31 308 * take u = z-v-1/2^32-1/2^64 */ 309 mpfr_inits2 (64, u, v, zz, (mpfr_ptr) 0); 310 mpfr_init2 (z, 32); 311 mpfr_set_str_binary (u, "0.10011000010011001110000100010001110010010000111001111110011"); 312 mpfr_set_str_binary (v, "0.1011110111110101011111011101100100110110111100011000000110011111"); 313 /* u + v = 1.0101011001000010010111101110101011111111111111111111111111111111 */ 314 inex = mpfr_add (zz, u, v, MPFR_RNDN); 315 MPFR_ASSERTN(inex > 0); 316 mpfr_set_str_binary (u, "1.01010110010000100101111011101011"); 317 MPFR_ASSERTN(mpfr_equal_p (zz, u)); 318 inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex); 319 /* we should have z = 1.0101011001000010010111101110101 and inex < 0 */ 320 MPFR_ASSERTN(inex < 0); 321 mpfr_set_str_binary (u, "1.0101011001000010010111101110101"); 322 MPFR_ASSERTN(mpfr_equal_p (z, u)); 323 mpfr_clears (u, v, zz, z, (mpfr_ptr) 0); 324 325 /* (64,128)-bit test: 326 * take for v a random 128-bit number in [1/2,1), 327 here v = 322263811942091240216761391118876232409/2^128 328 * take for z a random 64-bit number in [1,2), less than 2*v, 329 with last bit 0, here we take z = 16440347967874738276/2^63 330 * take u = z-v-1/2^64-1/2^128 */ 331 mpfr_inits2 (128, u, v, zz, (mpfr_ptr) 0); 332 mpfr_init2 (z, 64); 333 mpfr_set_str_binary (u, "0.1101010111011101111100100001011111111000010011011001000101111010110101101101011011100110101001010001101011011110101101010010011"); 334 mpfr_set_str_binary (v, "0.11110010011100011100000010100110100010011010110010111111010011000010100100101001000110010101101011100101001000010100101011011001"); 335 inex = mpfr_add (zz, u, v, MPFR_RNDN); 336 MPFR_ASSERTN(inex > 0); 337 mpfr_set_str_binary (u, "1.1100100001001111101100101011111010000001111110100101000011000111"); 338 MPFR_ASSERTN(mpfr_equal_p (zz, u)); 339 inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex); 340 MPFR_ASSERTN(inex < 0); 341 mpfr_set_str_binary (u, "1.1100100001001111101100101011111010000001111110100101000011000110"); 342 MPFR_ASSERTN(mpfr_equal_p (z, u)); 343 mpfr_clears (u, v, zz, z, (mpfr_ptr) 0); 344 } 345 346 #define TEST_FUNCTION mpfr_set 347 #include "tgeneric.c" 348 349 int 350 main (void) 351 { 352 mpfr_t x, y, z, u; 353 int inexact; 354 mpfr_exp_t emax; 355 356 tests_start_mpfr (); 357 358 test_set_1_2 (); 359 360 /* Default : no error */ 361 error = 0; 362 363 /* check prototypes of mpfr_init_set_* */ 364 inexact = mpfr_init_set_si (x, -1, MPFR_RNDN); 365 MPFR_ASSERTN (inexact == 0); 366 inexact = mpfr_init_set (y, x, MPFR_RNDN); 367 MPFR_ASSERTN (inexact == 0); 368 inexact = mpfr_init_set_ui (z, 1, MPFR_RNDN); 369 MPFR_ASSERTN (inexact == 0); 370 inexact = mpfr_init_set_d (u, 1.0, MPFR_RNDN); 371 MPFR_ASSERTN (inexact == 0); 372 373 emax = mpfr_get_emax (); 374 set_emax (0); 375 mpfr_set_prec (x, 3); 376 mpfr_set_str_binary (x, "0.111"); 377 mpfr_set_prec (y, 2); 378 mpfr_set (y, x, MPFR_RNDU); 379 if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y))) 380 { 381 printf ("Error for y=x=0.111 with px=3, py=2 and emax=0\nx="); 382 mpfr_dump (x); 383 printf ("y="); 384 mpfr_dump (y); 385 exit (1); 386 } 387 388 set_emax (emax); 389 390 mpfr_set_prec (y, 11); 391 mpfr_set_str_binary (y, "0.11111111100E-8"); 392 mpfr_set_prec (x, 2); 393 mpfr_set (x, y, MPFR_RNDN); 394 mpfr_set_str_binary (y, "1.0E-8"); 395 if (mpfr_cmp (x, y)) 396 { 397 printf ("Error for y=0.11111111100E-8, prec=2, rnd=MPFR_RNDN\n"); 398 exit (1); 399 } 400 401 mpfr_clear (x); 402 mpfr_clear (y); 403 mpfr_clear (z); 404 mpfr_clear (u); 405 406 check_ternary_value (); 407 check_special (); 408 check_neg_special (); 409 410 test_generic (MPFR_PREC_MIN, 1000, 10); 411 412 tests_end_mpfr (); 413 return error; 414 } 415