1/* Test file for mpfr_get_sj and mpfr_get_uj. 2 3Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4Contributed by the Arenaire and Cacao projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 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/* The ISO C99 standard specifies that in C++ implementations the 31 INTMAX_MAX, ... macros should only be defined if explicitly requested. */ 32#if defined __cplusplus 33# define __STDC_LIMIT_MACROS 34# define __STDC_CONSTANT_MACROS 35#endif 36 37#ifdef HAVE_STDINT_H 38# include <stdint.h> 39#endif 40#ifdef HAVE_INTTYPES_H 41# include <inttypes.h> 42#endif 43 44#include "mpfr-test.h" 45 46#ifndef _MPFR_H_HAVE_INTMAX_T 47 48int 49main (void) 50{ 51 return 0; 52} 53 54#else 55 56static void 57check_sj (intmax_t s, mpfr_ptr x) 58{ 59 mpfr_t y; 60 int i; 61 62 mpfr_init2 (y, MPFR_PREC (x)); 63 64 for (i = -1; i <= 1; i++) 65 { 66 int rnd; 67 68 mpfr_set_si_2exp (y, i, -2, MPFR_RNDN); 69 mpfr_add (y, y, x, MPFR_RNDN); 70 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 71 { 72 intmax_t r; 73 74 if (rnd == MPFR_RNDZ && i < 0 && s >= 0) 75 continue; 76 if (rnd == MPFR_RNDZ && i > 0 && s <= 0) 77 continue; 78 if (rnd == MPFR_RNDD && i < 0) 79 continue; 80 if (rnd == MPFR_RNDU && i > 0) 81 continue; 82 if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) || 83 (MPFR_IS_NEG(y) && i < 0))) 84 continue; 85 /* rint (y) == x == s */ 86 r = mpfr_get_sj (y, (mpfr_rnd_t) rnd); 87 if (r != s) 88 { 89 printf ("Error in check_sj for y = "); 90 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 91 printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 92 printf ("Got %jd instead of %jd.\n", r, s); 93 exit (1); 94 } 95 } 96 } 97 98 mpfr_clear (y); 99} 100 101static void 102check_uj (uintmax_t u, mpfr_ptr x) 103{ 104 mpfr_t y; 105 int i; 106 107 mpfr_init2 (y, MPFR_PREC (x)); 108 109 for (i = -1; i <= 1; i++) 110 { 111 int rnd; 112 113 mpfr_set_si_2exp (y, i, -2, MPFR_RNDN); 114 mpfr_add (y, y, x, MPFR_RNDN); 115 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 116 { 117 uintmax_t r; 118 119 if (rnd == MPFR_RNDZ && i < 0) 120 continue; 121 if (rnd == MPFR_RNDD && i < 0) 122 continue; 123 if (rnd == MPFR_RNDU && i > 0) 124 continue; 125 if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) || 126 (MPFR_IS_NEG(y) && i < 0))) 127 continue; 128 /* rint (y) == x == u */ 129 r = mpfr_get_uj (y, (mpfr_rnd_t) rnd); 130 if (r != u) 131 { 132 printf ("Error in check_uj for y = "); 133 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 134 printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 135 printf ("Got %ju instead of %ju.\n", r, u); 136 exit (1); 137 } 138 } 139 } 140 141 mpfr_clear (y); 142} 143 144static void 145check_erange (void) 146{ 147 mpfr_t x; 148 uintmax_t dl; 149 intmax_t d; 150 151 /* Test for ERANGE flag + correct behaviour if overflow */ 152 153 mpfr_init2 (x, 256); 154 mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN); 155 mpfr_clear_erangeflag (); 156 dl = mpfr_get_uj (x, MPFR_RNDN); 157 if (dl != MPFR_UINTMAX_MAX || mpfr_erangeflag_p ()) 158 { 159 printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (1)\n"); 160 exit (1); 161 } 162 mpfr_add_ui (x, x, 1, MPFR_RNDN); 163 dl = mpfr_get_uj (x, MPFR_RNDN); 164 if (dl != MPFR_UINTMAX_MAX || !mpfr_erangeflag_p ()) 165 { 166 printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (2)\n"); 167 exit (1); 168 } 169 mpfr_set_sj (x, -1, MPFR_RNDN); 170 mpfr_clear_erangeflag (); 171 dl = mpfr_get_uj (x, MPFR_RNDN); 172 if (dl != 0 || !mpfr_erangeflag_p ()) 173 { 174 printf ("ERROR for get_uj + ERANGE + -1 \n"); 175 exit (1); 176 } 177 mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN); 178 mpfr_clear_erangeflag (); 179 d = mpfr_get_sj (x, MPFR_RNDN); 180 if (d != MPFR_INTMAX_MAX || mpfr_erangeflag_p ()) 181 { 182 printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (1)\n"); 183 exit (1); 184 } 185 mpfr_add_ui (x, x, 1, MPFR_RNDN); 186 d = mpfr_get_sj (x, MPFR_RNDN); 187 if (d != MPFR_INTMAX_MAX || !mpfr_erangeflag_p ()) 188 { 189 printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (2)\n"); 190 exit (1); 191 } 192 mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN); 193 mpfr_clear_erangeflag (); 194 d = mpfr_get_sj (x, MPFR_RNDN); 195 if (d != MPFR_INTMAX_MIN || mpfr_erangeflag_p ()) 196 { 197 printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (1)\n"); 198 exit (1); 199 } 200 mpfr_sub_ui (x, x, 1, MPFR_RNDN); 201 d = mpfr_get_sj (x, MPFR_RNDN); 202 if (d != MPFR_INTMAX_MIN || !mpfr_erangeflag_p ()) 203 { 204 printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (2)\n"); 205 exit (1); 206 } 207 208 mpfr_set_nan (x); 209 mpfr_clear_erangeflag (); 210 d = mpfr_get_uj (x, MPFR_RNDN); 211 if (d != 0 || !mpfr_erangeflag_p ()) 212 { 213 printf ("ERROR for get_uj + NaN\n"); 214 exit (1); 215 } 216 mpfr_clear_erangeflag (); 217 d = mpfr_get_sj (x, MPFR_RNDN); 218 if (d != 0 || !mpfr_erangeflag_p ()) 219 { 220 printf ("ERROR for get_sj + NaN\n"); 221 exit (1); 222 } 223 224 mpfr_clear (x); 225} 226 227int 228main (void) 229{ 230 mpfr_prec_t prec; 231 mpfr_t x, y; 232 intmax_t s; 233 uintmax_t u; 234 235 tests_start_mpfr (); 236 237 for (u = MPFR_UINTMAX_MAX, prec = 0; u != 0; u /= 2, prec++) 238 { } 239 240 mpfr_init2 (x, prec + 4); 241 mpfr_init2 (y, prec + 4); 242 243 mpfr_set_ui (x, 0, MPFR_RNDN); 244 check_sj (0, x); 245 check_uj (0, x); 246 247 mpfr_set_si_2exp (x, 1, prec, MPFR_RNDN); 248 mpfr_sub_ui (x, x, 1, MPFR_RNDN); /* UINTMAX_MAX */ 249 250 mpfr_div_ui (y, x, 2, MPFR_RNDZ); 251 mpfr_trunc (y, y); /* INTMAX_MAX */ 252 for (s = MPFR_INTMAX_MAX; s != 0; s /= 17) 253 { 254 check_sj (s, y); 255 mpfr_div_ui (y, y, 17, MPFR_RNDZ); 256 mpfr_trunc (y, y); 257 } 258 259 mpfr_div_ui (y, x, 2, MPFR_RNDZ); 260 mpfr_trunc (y, y); /* INTMAX_MAX */ 261 mpfr_neg (y, y, MPFR_RNDN); 262 if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0) 263 mpfr_sub_ui (y, y, 1, MPFR_RNDN); /* INTMAX_MIN */ 264 for (s = MPFR_INTMAX_MIN; s != 0; s /= 17) 265 { 266 check_sj (s, y); 267 mpfr_div_ui (y, y, 17, MPFR_RNDZ); 268 mpfr_trunc (y, y); 269 } 270 271 for (u = MPFR_UINTMAX_MAX; u != 0; u /= 17) 272 { 273 check_uj (u, x); 274 mpfr_div_ui (x, x, 17, MPFR_RNDZ); 275 mpfr_trunc (x, x); 276 } 277 278 mpfr_clear (x); 279 mpfr_clear (y); 280 281 check_erange (); 282 283 tests_end_mpfr (); 284 return 0; 285} 286 287#endif 288