1 /* Test file for mpfr_get_sj and mpfr_get_uj. 2 3 Copyright 2004-2016 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 #ifdef HAVE_CONFIG_H 24 # include "config.h" /* for a build within gmp */ 25 #endif 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 30 #include "mpfr-intmax.h" 31 #include "mpfr-test.h" 32 33 #ifndef _MPFR_H_HAVE_INTMAX_T 34 35 int 36 main (void) 37 { 38 return 77; 39 } 40 41 #else 42 43 static void 44 check_sj (intmax_t s, mpfr_ptr x) 45 { 46 mpfr_t y; 47 int i; 48 49 mpfr_init2 (y, MPFR_PREC (x)); 50 51 for (i = -1; i <= 1; i++) 52 { 53 int rnd; 54 55 mpfr_set_si_2exp (y, i, -2, MPFR_RNDN); 56 mpfr_add (y, y, x, MPFR_RNDN); 57 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 58 { 59 intmax_t r; 60 61 if (rnd == MPFR_RNDZ && i < 0 && s >= 0) 62 continue; 63 if (rnd == MPFR_RNDZ && i > 0 && s <= 0) 64 continue; 65 if (rnd == MPFR_RNDD && i < 0) 66 continue; 67 if (rnd == MPFR_RNDU && i > 0) 68 continue; 69 if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) || 70 (MPFR_IS_NEG(y) && i < 0))) 71 continue; 72 /* rint (y) == x == s */ 73 r = mpfr_get_sj (y, (mpfr_rnd_t) rnd); 74 if (r != s) 75 { 76 printf ("Error in check_sj for y = "); 77 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 78 printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 79 printf ("Got %jd instead of %jd.\n", r, s); 80 exit (1); 81 } 82 } 83 } 84 85 mpfr_clear (y); 86 } 87 88 static void 89 check_uj (uintmax_t u, mpfr_ptr x) 90 { 91 mpfr_t y; 92 int i; 93 94 mpfr_init2 (y, MPFR_PREC (x)); 95 96 for (i = -1; i <= 1; i++) 97 { 98 int rnd; 99 100 mpfr_set_si_2exp (y, i, -2, MPFR_RNDN); 101 mpfr_add (y, y, x, MPFR_RNDN); 102 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 103 { 104 uintmax_t r; 105 106 if (rnd == MPFR_RNDZ && i < 0) 107 continue; 108 if (rnd == MPFR_RNDD && i < 0) 109 continue; 110 if (rnd == MPFR_RNDU && i > 0) 111 continue; 112 if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) || 113 (MPFR_IS_NEG(y) && i < 0))) 114 continue; 115 /* rint (y) == x == u */ 116 r = mpfr_get_uj (y, (mpfr_rnd_t) rnd); 117 if (r != u) 118 { 119 printf ("Error in check_uj for y = "); 120 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 121 printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 122 printf ("Got %ju instead of %ju.\n", r, u); 123 exit (1); 124 } 125 } 126 } 127 128 mpfr_clear (y); 129 } 130 131 static void 132 check_erange (void) 133 { 134 mpfr_t x; 135 uintmax_t dl; 136 intmax_t d; 137 138 /* Test for ERANGE flag + correct behaviour if overflow */ 139 140 mpfr_init2 (x, 256); 141 mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN); 142 mpfr_clear_erangeflag (); 143 dl = mpfr_get_uj (x, MPFR_RNDN); 144 if (dl != MPFR_UINTMAX_MAX || mpfr_erangeflag_p ()) 145 { 146 printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (1)\n"); 147 exit (1); 148 } 149 mpfr_add_ui (x, x, 1, MPFR_RNDN); 150 dl = mpfr_get_uj (x, MPFR_RNDN); 151 if (dl != MPFR_UINTMAX_MAX || !mpfr_erangeflag_p ()) 152 { 153 printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (2)\n"); 154 exit (1); 155 } 156 mpfr_set_sj (x, -1, MPFR_RNDN); 157 mpfr_clear_erangeflag (); 158 dl = mpfr_get_uj (x, MPFR_RNDN); 159 if (dl != 0 || !mpfr_erangeflag_p ()) 160 { 161 printf ("ERROR for get_uj + ERANGE + -1 \n"); 162 exit (1); 163 } 164 mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN); 165 mpfr_clear_erangeflag (); 166 d = mpfr_get_sj (x, MPFR_RNDN); 167 if (d != MPFR_INTMAX_MAX || mpfr_erangeflag_p ()) 168 { 169 printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (1)\n"); 170 exit (1); 171 } 172 mpfr_add_ui (x, x, 1, MPFR_RNDN); 173 d = mpfr_get_sj (x, MPFR_RNDN); 174 if (d != MPFR_INTMAX_MAX || !mpfr_erangeflag_p ()) 175 { 176 printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (2)\n"); 177 exit (1); 178 } 179 mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN); 180 mpfr_clear_erangeflag (); 181 d = mpfr_get_sj (x, MPFR_RNDN); 182 if (d != MPFR_INTMAX_MIN || mpfr_erangeflag_p ()) 183 { 184 printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (1)\n"); 185 exit (1); 186 } 187 mpfr_sub_ui (x, x, 1, MPFR_RNDN); 188 d = mpfr_get_sj (x, MPFR_RNDN); 189 if (d != MPFR_INTMAX_MIN || !mpfr_erangeflag_p ()) 190 { 191 printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (2)\n"); 192 exit (1); 193 } 194 195 mpfr_set_nan (x); 196 mpfr_clear_erangeflag (); 197 d = mpfr_get_uj (x, MPFR_RNDN); 198 if (d != 0 || !mpfr_erangeflag_p ()) 199 { 200 printf ("ERROR for get_uj + NaN\n"); 201 exit (1); 202 } 203 mpfr_clear_erangeflag (); 204 d = mpfr_get_sj (x, MPFR_RNDN); 205 if (d != 0 || !mpfr_erangeflag_p ()) 206 { 207 printf ("ERROR for get_sj + NaN\n"); 208 exit (1); 209 } 210 211 mpfr_clear (x); 212 } 213 214 int 215 main (void) 216 { 217 mpfr_prec_t prec; 218 mpfr_t x, y; 219 intmax_t s; 220 uintmax_t u; 221 222 tests_start_mpfr (); 223 224 for (u = MPFR_UINTMAX_MAX, prec = 0; u != 0; u /= 2, prec++) 225 { } 226 227 mpfr_init2 (x, prec + 4); 228 mpfr_init2 (y, prec + 4); 229 230 mpfr_set_ui (x, 0, MPFR_RNDN); 231 check_sj (0, x); 232 check_uj (0, x); 233 234 mpfr_set_ui (x, 1, MPFR_RNDN); 235 check_sj (1, x); 236 check_uj (1, x); 237 238 mpfr_neg (x, x, MPFR_RNDN); 239 check_sj (-1, x); 240 241 mpfr_set_si_2exp (x, 1, prec, MPFR_RNDN); 242 mpfr_sub_ui (x, x, 1, MPFR_RNDN); /* UINTMAX_MAX */ 243 244 mpfr_div_ui (y, x, 2, MPFR_RNDZ); 245 mpfr_trunc (y, y); /* INTMAX_MAX */ 246 for (s = MPFR_INTMAX_MAX; s != 0; s /= 17) 247 { 248 check_sj (s, y); 249 mpfr_div_ui (y, y, 17, MPFR_RNDZ); 250 mpfr_trunc (y, y); 251 } 252 253 mpfr_div_ui (y, x, 2, MPFR_RNDZ); 254 mpfr_trunc (y, y); /* INTMAX_MAX */ 255 mpfr_neg (y, y, MPFR_RNDN); 256 if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0) 257 mpfr_sub_ui (y, y, 1, MPFR_RNDN); /* INTMAX_MIN */ 258 for (s = MPFR_INTMAX_MIN; s != 0; s /= 17) 259 { 260 check_sj (s, y); 261 mpfr_div_ui (y, y, 17, MPFR_RNDZ); 262 mpfr_trunc (y, y); 263 } 264 265 for (u = MPFR_UINTMAX_MAX; u != 0; u /= 17) 266 { 267 check_uj (u, x); 268 mpfr_div_ui (x, x, 17, MPFR_RNDZ); 269 mpfr_trunc (x, x); 270 } 271 272 mpfr_clear (x); 273 mpfr_clear (y); 274 275 check_erange (); 276 277 tests_end_mpfr (); 278 return 0; 279 } 280 281 #endif 282