1 /* Test file for mpfr_set. 2 3 Copyright 2001-2018 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 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 "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 #define TEST_FUNCTION mpfr_set 260 #include "tgeneric.c" 261 262 int 263 main (void) 264 { 265 mpfr_t x, y, z, u; 266 int inexact; 267 mpfr_exp_t emax; 268 269 tests_start_mpfr (); 270 271 /* Default : no error */ 272 error = 0; 273 274 /* check prototypes of mpfr_init_set_* */ 275 inexact = mpfr_init_set_si (x, -1, MPFR_RNDN); 276 MPFR_ASSERTN (inexact == 0); 277 inexact = mpfr_init_set (y, x, MPFR_RNDN); 278 MPFR_ASSERTN (inexact == 0); 279 inexact = mpfr_init_set_ui (z, 1, MPFR_RNDN); 280 MPFR_ASSERTN (inexact == 0); 281 inexact = mpfr_init_set_d (u, 1.0, MPFR_RNDN); 282 MPFR_ASSERTN (inexact == 0); 283 284 emax = mpfr_get_emax (); 285 set_emax (0); 286 mpfr_set_prec (x, 3); 287 mpfr_set_str_binary (x, "0.111"); 288 mpfr_set_prec (y, 2); 289 mpfr_set (y, x, MPFR_RNDU); 290 if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y))) 291 { 292 printf ("Error for y=x=0.111 with px=3, py=2 and emax=0\nx="); 293 mpfr_dump (x); 294 printf ("y="); 295 mpfr_dump (y); 296 exit (1); 297 } 298 299 set_emax (emax); 300 301 mpfr_set_prec (y, 11); 302 mpfr_set_str_binary (y, "0.11111111100E-8"); 303 mpfr_set_prec (x, 2); 304 mpfr_set (x, y, MPFR_RNDN); 305 mpfr_set_str_binary (y, "1.0E-8"); 306 if (mpfr_cmp (x, y)) 307 { 308 printf ("Error for y=0.11111111100E-8, prec=2, rnd=MPFR_RNDN\n"); 309 exit (1); 310 } 311 312 mpfr_clear (x); 313 mpfr_clear (y); 314 mpfr_clear (z); 315 mpfr_clear (u); 316 317 check_ternary_value (); 318 check_special (); 319 check_neg_special (); 320 321 test_generic (MPFR_PREC_MIN, 1000, 10); 322 323 tests_end_mpfr (); 324 return error; 325 } 326