1/* tsprintf.c -- test file for mpfr_sprintf, mpfr_vsprintf, mpfr_snprintf, 2 and mpfr_vsnprintf 3 4Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 5Contributed by the Arenaire and Cacao projects, INRIA. 6 7The GNU MPFR Library is free software; you can redistribute it and/or modify 8it under the terms of the GNU Lesser General Public License as published by 9the Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The GNU MPFR Library is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15License for more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 19http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2051 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 22#ifdef HAVE_STDARG 23#include <stdarg.h> 24 25#include <stdlib.h> 26#include <float.h> 27 28#ifdef HAVE_LOCALE_H 29#include <locale.h> 30#endif 31 32#include "mpfr-test.h" 33 34#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) 35 36const int prec_max_printf = 5000; /* limit for random precision in 37 random_double() */ 38#define BUF_SIZE 65536 39 40const char pinf_str[] = "inf"; 41const char pinf_uc_str[] = "INF"; 42const char minf_str[] = "-inf"; 43const char minf_uc_str[] = "-INF"; 44const char nan_str[] = "nan"; 45const char nan_uc_str[] = "NAN"; 46 47/* 1. compare expected string with the string BUFFER returned by 48 mpfr_sprintf(buffer, fmt, x) 49 2. then test mpfr_snprintf (buffer, p, fmt, x) with a random p. */ 50static int 51check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x) 52{ 53 int n0, n1, p; 54 char buffer[BUF_SIZE]; 55 56 /* test mpfr_sprintf */ 57 n0 = mpfr_sprintf (buffer, fmt, x); 58 if (strcmp (buffer, expected) != 0) 59 { 60 printf ("Error in mpfr_sprintf (s, \"%s\", x);\n", fmt); 61 printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer); 62 63 exit (1); 64 } 65 66 /* test mpfr_snprintf */ 67 p = (int) (randlimb () % n0); 68 if (p == 0 && (randlimb () & 1) == 0) 69 { 70 n1 = mpfr_snprintf (NULL, 0, fmt, x); 71 } 72 else 73 { 74 buffer[p] = 17; 75 n1 = mpfr_snprintf (buffer, p, fmt, x); 76 if (buffer[p] != 17) 77 { 78 printf ("Buffer overflow in mpfr_snprintf for p = %d!\n", p); 79 exit (1); 80 } 81 } 82 if (n0 != n1) 83 { 84 printf ("Error in mpfr_snprintf (s, %d, \"%s\", x) return value\n", 85 p, fmt); 86 printf ("expected: %d\ngot: %d\n", n0, n1); 87 exit (1); 88 } 89 if ((p > 1 && strncmp (expected, buffer, p-1) != 0) 90 || (p == 1 && buffer[0] != '\0')) 91 { 92 char part_expected[BUF_SIZE]; 93 strncpy (part_expected, expected, p); 94 part_expected[p-1] = '\0'; 95 printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt); 96 printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer); 97 exit (1); 98 } 99 return n0; 100} 101 102/* 1. compare expected string with the string BUFFER returned by 103 mpfr_vsprintf(buffer, fmt, ...) 104 2. then, test mpfr_vsnprintf. */ 105static int 106check_vsprintf (const char *expected, const char *fmt, ...) 107{ 108 int n0, n1, p; 109 char buffer[BUF_SIZE]; 110 va_list ap0, ap1; 111 va_start (ap0, fmt); 112 va_start (ap1, fmt); 113 114 n0 = mpfr_vsprintf (buffer, fmt, ap0); 115 if (strcmp (buffer, expected) != 0) 116 { 117 printf ("Error in mpfr_vsprintf (s, \"%s\", ...);\n", fmt); 118 printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer); 119 120 va_end (ap0); 121 va_end (ap1); 122 exit (1); 123 } 124 va_end (ap0); 125 126 /* test mpfr_snprintf */ 127 p = (int) (randlimb () % n0); 128 if (p == 0 && (randlimb () & 1) == 0) 129 { 130 n1 = mpfr_vsnprintf (NULL, 0, fmt, ap1); 131 } 132 else 133 { 134 buffer[p] = 17; 135 n1 = mpfr_vsnprintf (buffer, p, fmt, ap1); 136 if (buffer[p] != 17) 137 { 138 printf ("Buffer overflow in mpfr_vsnprintf for p = %d!\n", p); 139 exit (1); 140 } 141 } 142 if (n0 != n1) 143 { 144 printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...) return value\n", 145 p, fmt); 146 printf ("expected: %d\ngot: %d\n", n0, n1); 147 148 va_end (ap1); 149 exit (1); 150 } 151 if ((p > 1 && strncmp (expected, buffer, p-1) != 0) 152 || (p == 1 && buffer[0] != '\0')) 153 { 154 char part_expected[BUF_SIZE]; 155 strncpy (part_expected, expected, p); 156 part_expected[p-1] = '\0'; 157 printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt); 158 printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer); 159 160 va_end (ap1); 161 exit (1); 162 } 163 164 va_end (ap1); 165 return n0; 166} 167 168static void 169native_types (void) 170{ 171 int c = 'a'; 172 int i = -1; 173 unsigned int ui = 1; 174 double d = -1.25; 175 char s[] = "test"; 176 177 char buf[255]; 178 179 sprintf (buf, "%c", c); 180 check_vsprintf (buf, "%c", c); 181 182 sprintf (buf, "%d", i); 183 check_vsprintf (buf, "%d", i); 184 185 sprintf (buf, "%e", d); 186 check_vsprintf (buf, "%e", d); 187 188 sprintf (buf, "%f", d); 189 check_vsprintf (buf, "%f", d); 190 191 sprintf (buf, "%i", i); 192 check_vsprintf (buf, "%i", i); 193 194 sprintf (buf, "%g", d); 195 check_vsprintf (buf, "%g", d); 196 197 sprintf (buf, "%o", i); 198 check_vsprintf (buf, "%o", i); 199 200 sprintf (buf, "%s", s); 201 check_vsprintf (buf, "%s", s); 202 203 sprintf (buf, "--%s++", ""); 204 check_vsprintf (buf, "--%s++", ""); 205 206 sprintf (buf, "%u", ui); 207 check_vsprintf (buf, "%u", ui); 208 209 sprintf (buf, "%x", ui); 210 check_vsprintf (buf, "%x", ui); 211} 212 213static int 214decimal (void) 215{ 216 mpfr_prec_t p = 128; 217 mpfr_t x; 218 mpfr_t z; 219 mpfr_init (z); 220 mpfr_init2 (x, p); 221 222 /* specifier 'P' for precision */ 223 check_vsprintf ("128", "%Pu", p); 224 check_vsprintf ("00128", "%.5Pu", p); 225 226 /* special numbers */ 227 mpfr_set_inf (x, 1); 228 check_sprintf (pinf_str, "%Re", x); 229 check_sprintf (pinf_str, "%RUe", x); 230 check_sprintf (pinf_uc_str, "%RE", x); 231 check_sprintf (pinf_uc_str, "%RDE", x); 232 check_sprintf (pinf_str, "%Rf", x); 233 check_sprintf (pinf_str, "%RYf", x); 234 check_sprintf (pinf_uc_str, "%RF", x); 235 check_sprintf (pinf_uc_str, "%RZF", x); 236 check_sprintf (pinf_str, "%Rg", x); 237 check_sprintf (pinf_str, "%RNg", x); 238 check_sprintf (pinf_uc_str, "%RG", x); 239 check_sprintf (pinf_uc_str, "%RUG", x); 240 check_sprintf (" inf", "%010Re", x); 241 check_sprintf (" inf", "%010RDe", x); 242 243 mpfr_set_inf (x, -1); 244 check_sprintf (minf_str, "%Re", x); 245 check_sprintf (minf_str, "%RYe", x); 246 check_sprintf (minf_uc_str, "%RE", x); 247 check_sprintf (minf_uc_str, "%RZE", x); 248 check_sprintf (minf_str, "%Rf", x); 249 check_sprintf (minf_str, "%RNf", x); 250 check_sprintf (minf_uc_str, "%RF", x); 251 check_sprintf (minf_uc_str, "%RUF", x); 252 check_sprintf (minf_str, "%Rg", x); 253 check_sprintf (minf_str, "%RDg", x); 254 check_sprintf (minf_uc_str, "%RG", x); 255 check_sprintf (minf_uc_str, "%RYG", x); 256 check_sprintf (" -inf", "%010Re", x); 257 check_sprintf (" -inf", "%010RZe", x); 258 259 mpfr_set_nan (x); 260 check_sprintf (nan_str, "%Re", x); 261 check_sprintf (nan_str, "%RNe", x); 262 check_sprintf (nan_uc_str, "%RE", x); 263 check_sprintf (nan_uc_str, "%RUE", x); 264 check_sprintf (nan_str, "%Rf", x); 265 check_sprintf (nan_str, "%RDf", x); 266 check_sprintf (nan_uc_str, "%RF", x); 267 check_sprintf (nan_uc_str, "%RYF", x); 268 check_sprintf (nan_str, "%Rg", x); 269 check_sprintf (nan_str, "%RZg", x); 270 check_sprintf (nan_uc_str, "%RG", x); 271 check_sprintf (nan_uc_str, "%RNG", x); 272 check_sprintf (" nan", "%010Re", x); 273 274 /* positive numbers */ 275 mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN); 276 mpfr_set_ui (z, 0, MPFR_RNDD); 277 278 /* simplest case right justified */ 279 check_sprintf (" 1.899347461279296875e+07", "%30Re", x); 280 check_sprintf (" 2e+07", "%30.0Re", x); 281 check_sprintf (" 18993474.612793", "%30Rf", x); 282 check_sprintf (" 18993474.6127930", "%30.7Rf", x); 283 check_sprintf (" 1.89935e+07", "%30Rg", x); 284 check_sprintf (" 2e+07", "%30.0Rg", x); 285 check_sprintf (" 18993474.61279296875", "%30.19Rg", x); 286 check_sprintf (" 0e+00", "%30.0Re", z); 287 check_sprintf (" 0", "%30.0Rf", z); 288 check_sprintf (" 0.0000", "%30.4Rf", z); 289 check_sprintf (" 0", "%30.0Rg", z); 290 check_sprintf (" 0", "%30.4Rg", z); 291 /* sign or space, pad with leading zeros */ 292 check_sprintf (" 000001.899347461279296875E+07", "% 030RE", x); 293 check_sprintf (" 0000000000000000001.89935E+07", "% 030RG", x); 294 check_sprintf (" 0000000000000000000000002E+07", "% 030.0RE", x); 295 check_sprintf (" 0000000000000000000000000E+00", "% 030.0RE", z); 296 check_sprintf (" 00000000000000000000000000000", "% 030.0RF", z); 297 /* sign + or -, left justified */ 298 check_sprintf ("+1.899347461279296875e+07 ", "%+-30Re", x); 299 check_sprintf ("+2e+07 ", "%+-30.0Re", x); 300 check_sprintf ("+0e+00 ", "%+-30.0Re", z); 301 check_sprintf ("+0 ", "%+-30.0Rf", z); 302 /* decimal point, left justified, precision and rounding parameter */ 303 check_vsprintf ("1.9E+07 ", "%#-10.*R*E", 1, MPFR_RNDN, x); 304 check_vsprintf ("2.E+07 ", "%#*.*R*E", -10, 0, MPFR_RNDN, x); 305 check_vsprintf ("2.E+07 ", "%#-10.*R*G", 0, MPFR_RNDN, x); 306 check_vsprintf ("0.E+00 ", "%#-10.*R*E", 0, MPFR_RNDN, z); 307 check_vsprintf ("0. ", "%#-10.*R*F", 0, MPFR_RNDN, z); 308 check_vsprintf ("0. ", "%#-10.*R*G", 0, MPFR_RNDN, z); 309 /* sign or space */ 310 check_sprintf (" 1.899e+07", "% .3RNe", x); 311 check_sprintf (" 2e+07", "% .0RNe", x); 312 /* sign + or -, decimal point, pad with leading zeros */ 313 check_sprintf ("+0001.8E+07", "%0+#11.1RZE", x); 314 check_sprintf ("+00001.E+07", "%0+#11.0RZE", x); 315 check_sprintf ("+0000.0E+00", "%0+#11.1RZE", z); 316 check_sprintf ("+00000000.0", "%0+#11.1RZF", z); 317 /* pad with leading zero */ 318 check_sprintf ("0000001.899347461279296875e+07", "%030RDe", x); 319 check_sprintf ("00000000000000000000000001e+07", "%030.0RDe", x); 320 /* sign or space, decimal point, left justified */ 321 check_sprintf (" 1.8E+07 ", "%- #11.1RDE", x); 322 check_sprintf (" 1.E+07 ", "%- #11.0RDE", x); 323 324 /* negative numbers */ 325 mpfr_mul_si (x, x, -1, MPFR_RNDD); 326 mpfr_mul_si (z, z, -1, MPFR_RNDD); 327 328 /* sign + or - */ 329 check_sprintf (" -1.8e+07", "%+10.1RUe", x); 330 check_sprintf (" -1e+07", "%+10.0RUe", x); 331 check_sprintf (" -0e+00", "%+10.0RUe", z); 332 check_sprintf (" -0", "%+10.0RUf", z); 333 334 335 /* neighborhood of 1 */ 336 mpfr_set_str (x, "0.99993896484375", 10, MPFR_RNDN); 337 check_sprintf ("9.9993896484375E-01 ", "%-20RE", x); 338 check_sprintf ("9.9993896484375E-01 ", "%-20.RE", x); 339 check_sprintf ("1E+00 ", "%-20.0RE", x); 340 check_sprintf ("1.0E+00 ", "%-20.1RE", x); 341 check_sprintf ("1.00E+00 ", "%-20.2RE", x); 342 check_sprintf ("9.999E-01 ", "%-20.3RE", x); 343 check_sprintf ("9.9994E-01 ", "%-20.4RE", x); 344 check_sprintf ("0.999939 ", "%-20RF", x); 345 check_sprintf ("0.999939 ", "%-20.RF", x); 346 check_sprintf ("1 ", "%-20.0RF", x); 347 check_sprintf ("1.0 ", "%-20.1RF", x); 348 check_sprintf ("1.00 ", "%-20.2RF", x); 349 check_sprintf ("1.000 ", "%-20.3RF", x); 350 check_sprintf ("0.9999 ", "%-20.4RF", x); 351 check_sprintf ("0.999939 ", "%-#20RF", x); 352 check_sprintf ("0.999939 ", "%-#20.RF", x); 353 check_sprintf ("1. ", "%-#20.0RF", x); 354 check_sprintf ("1.0 ", "%-#20.1RF", x); 355 check_sprintf ("1.00 ", "%-#20.2RF", x); 356 check_sprintf ("1.000 ", "%-#20.3RF", x); 357 check_sprintf ("0.9999 ", "%-#20.4RF", x); 358 check_sprintf ("1 ", "%-20.0RG", x); 359 check_sprintf ("1 ", "%-20.1RG", x); 360 check_sprintf ("1 ", "%-20.2RG", x); 361 check_sprintf ("1 ", "%-20.3RG", x); 362 check_sprintf ("0.9999 ", "%-20.4RG", x); 363 check_sprintf ("0.999939 ", "%-#20RG", x); 364 check_sprintf ("0.999939 ", "%-#20.RG", x); 365 check_sprintf ("1. ", "%-#20.0RG", x); 366 check_sprintf ("1. ", "%-#20.1RG", x); 367 check_sprintf ("1.0 ", "%-#20.2RG", x); 368 check_sprintf ("1.00 ", "%-#20.3RG", x); 369 check_sprintf ("0.9999 ", "%-#20.4RG", x); 370 371 /* multiple of 10 */ 372 mpfr_set_str (x, "1e17", 10, MPFR_RNDN); 373 check_sprintf ("1e+17", "%Re", x); 374 check_sprintf ("1.000e+17", "%.3Re", x); 375 check_sprintf ("100000000000000000", "%.0Rf", x); 376 check_sprintf ("100000000000000000.0", "%.1Rf", x); 377 check_sprintf ("100000000000000000.000000", "%'Rf", x); 378 check_sprintf ("100000000000000000.0", "%'.1Rf", x); 379 380 mpfr_ui_div (x, 1, x, MPFR_RNDN); /* x=1e-17 */ 381 check_sprintf ("1e-17", "%Re", x); 382 check_sprintf ("0.000000", "%Rf", x); 383 check_sprintf ("1e-17", "%Rg", x); 384 check_sprintf ("0.0", "%.1RDf", x); 385 check_sprintf ("0.0", "%.1RZf", x); 386 check_sprintf ("0.1", "%.1RUf", x); 387 check_sprintf ("0.1", "%.1RYf", x); 388 check_sprintf ("0", "%.0RDf", x); 389 check_sprintf ("0", "%.0RZf", x); 390 check_sprintf ("1", "%.0RUf", x); 391 check_sprintf ("1", "%.0RYf", x); 392 393 /* check rounding mode */ 394 mpfr_set_str (x, "0.0076", 10, MPFR_RNDN); 395 check_sprintf ("0.007", "%.3RDF", x); 396 check_sprintf ("0.007", "%.3RZF", x); 397 check_sprintf ("0.008", "%.3RF", x); 398 check_sprintf ("0.008", "%.3RUF", x); 399 check_sprintf ("0.008", "%.3RYF", x); 400 check_vsprintf ("0.008", "%.3R*F", MPFR_RNDA, x); 401 402 /* check limit between %f-style and %g-style */ 403 mpfr_set_str (x, "0.0000999", 10, MPFR_RNDN); 404 check_sprintf ("0.0001", "%.0Rg", x); 405 check_sprintf ("9e-05", "%.0RDg", x); 406 check_sprintf ("0.0001", "%.1Rg", x); 407 check_sprintf ("0.0001", "%.2Rg", x); 408 check_sprintf ("9.99e-05", "%.3Rg", x); 409 410 /* trailing zeros */ 411 mpfr_set_si_2exp (x, -1, -15, MPFR_RNDN); /* x=-2^-15 */ 412 check_sprintf ("-3.0517578125e-05", "%.30Rg", x); 413 check_sprintf ("-3.051757812500000000000000000000e-05", "%.30Re", x); 414 check_sprintf ("-3.05175781250000000000000000000e-05", "%#.30Rg", x); 415 check_sprintf ("-0.000030517578125000000000000000", "%.30Rf", x); 416 417 /* bug 20081023 */ 418 check_sprintf ("-3.0517578125e-05", "%.30Rg", x); 419 mpfr_set_str (x, "1.9999", 10, MPFR_RNDN); 420 check_sprintf ("1.999900 ", "%-#10.7RG", x); 421 check_sprintf ("1.9999 ", "%-10.7RG", x); 422 mpfr_set_ui (x, 1, MPFR_RNDN); 423 check_sprintf ("1.00000000000000000000000000000", "%#.30Rg", x); 424 check_sprintf ("1", "%.30Rg", x); 425 mpfr_set_ui (x, 0, MPFR_RNDN); 426 check_sprintf ("0.000000000000000000000000000000", "%#.30Rg", x); 427 check_sprintf ("0", "%.30Rg", x); 428 429 /* following tests with precision 53 bits */ 430 mpfr_set_prec (x, 53); 431 432 /* Exponent zero has a plus sign */ 433 mpfr_set_str (x, "-9.95645044213728791504536275169812142849e-01", 10, 434 MPFR_RNDN); 435 check_sprintf ("-1.0e+00", "%- #0.1Re", x); 436 437 /* Decimal point and no figure after it with '#' flag and 'G' style */ 438 mpfr_set_str (x, "-9.90597761233942053494e-01", 10, MPFR_RNDN); 439 check_sprintf ("-1.", "%- #0.1RG", x); 440 441 /* precision zero */ 442 mpfr_set_d (x, -9.5, MPFR_RNDN); 443 check_sprintf ("-10", "%.0RDf", x); 444 check_sprintf ("-10", "%.0RYf", x); 445 check_sprintf ("-10", "%.0Rf", x); 446 check_sprintf ("-1e+01", "%.0Re", x); 447 check_sprintf ("-1e+01", "%.0Rg", x); 448 mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN); 449 check_sprintf ("0", "%.0Rf", x); 450 check_sprintf ("5e-01", "%.0Re", x); 451 check_sprintf ("0.5", "%.0Rg", x); 452 mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN); 453 check_sprintf ("2", "%.0Rf", x); 454 mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN); 455 check_sprintf ("2", "%.0Rf", x); 456 mpfr_set_ui (x, 0x1f, MPFR_RNDN); 457 check_sprintf ("0x1p+5", "%.0Ra", x); 458 mpfr_set_ui (x, 3, MPFR_RNDN); 459 check_sprintf ("1p+2", "%.0Rb", x); 460 461 /* round to next ten power with %f but not with %g */ 462 mpfr_set_str (x, "-6.64464380544039223686e-02", 10, MPFR_RNDN); 463 check_sprintf ("-0.1", "%.1Rf", x); 464 check_sprintf ("-0.0", "%.1RZf", x); 465 check_sprintf ("-0.07", "%.1Rg", x); 466 check_sprintf ("-0.06", "%.1RZg", x); 467 468 /* round to next ten power and do not remove trailing zeros */ 469 mpfr_set_str (x, "9.98429393291486722006e-02", 10, MPFR_RNDN); 470 check_sprintf ("0.1", "%#.1Rg", x); 471 check_sprintf ("0.10", "%#.2Rg", x); 472 check_sprintf ("0.099", "%#.2RZg", x); 473 474 /* Halfway cases */ 475 mpfr_set_str (x, "1.5", 10, MPFR_RNDN); 476 check_sprintf ("2e+00", "%.0Re", x); 477 mpfr_set_str (x, "2.5", 10, MPFR_RNDN); 478 check_sprintf ("2e+00", "%.0Re", x); 479 mpfr_set_str (x, "9.5", 10, MPFR_RNDN); 480 check_sprintf ("1e+01", "%.0Re", x); 481 mpfr_set_str (x, "1.25", 10, MPFR_RNDN); 482 check_sprintf ("1.2e+00", "%.1Re", x); 483 mpfr_set_str (x, "1.75", 10, MPFR_RNDN); 484 check_sprintf ("1.8e+00", "%.1Re", x); 485 mpfr_set_str (x, "-0.5", 10, MPFR_RNDN); 486 check_sprintf ("-0", "%.0Rf", x); 487 mpfr_set_str (x, "1.25", 10, MPFR_RNDN); 488 check_sprintf ("1.2", "%.1Rf", x); 489 mpfr_set_str (x, "1.75", 10, MPFR_RNDN); 490 check_sprintf ("1.8", "%.1Rf", x); 491 mpfr_set_str (x, "1.5", 10, MPFR_RNDN); 492 check_sprintf ("2", "%.1Rg", x); 493 mpfr_set_str (x, "2.5", 10, MPFR_RNDN); 494 check_sprintf ("2", "%.1Rg", x); 495 mpfr_set_str (x, "9.25", 10, MPFR_RNDN); 496 check_sprintf ("9.2", "%.2Rg", x); 497 mpfr_set_str (x, "9.75", 10, MPFR_RNDN); 498 check_sprintf ("9.8", "%.2Rg", x); 499 500 /* assertion failure in r6320 */ 501 mpfr_set_str (x, "-9.996", 10, MPFR_RNDN); 502 check_sprintf ("-10.0", "%.1Rf", x); 503 504 mpfr_clears (x, z, (mpfr_ptr) 0); 505 return 0; 506} 507 508static int 509hexadecimal (void) 510{ 511 mpfr_t x, z; 512 mpfr_inits2 (64, x, z, (mpfr_ptr) 0); 513 514 /* special */ 515 mpfr_set_inf (x, 1); 516 check_sprintf (pinf_str, "%Ra", x); 517 check_sprintf (pinf_str, "%RUa", x); 518 check_sprintf (pinf_str, "%RDa", x); 519 check_sprintf (pinf_uc_str, "%RA", x); 520 check_sprintf (pinf_uc_str, "%RYA", x); 521 check_sprintf (pinf_uc_str, "%RZA", x); 522 check_sprintf (pinf_uc_str, "%RNA", x); 523 524 mpfr_set_inf (x, -1); 525 check_sprintf (minf_str, "%Ra", x); 526 check_sprintf (minf_str, "%RYa", x); 527 check_sprintf (minf_str, "%RZa", x); 528 check_sprintf (minf_str, "%RNa", x); 529 check_sprintf (minf_uc_str, "%RA", x); 530 check_sprintf (minf_uc_str, "%RUA", x); 531 check_sprintf (minf_uc_str, "%RDA", x); 532 533 mpfr_set_nan (x); 534 check_sprintf (nan_str, "%Ra", x); 535 check_sprintf (nan_uc_str, "%RA", x); 536 537 /* regular numbers */ 538 mpfr_set_str (x, "FEDCBA9.87654321", 16, MPFR_RNDN); 539 mpfr_set_ui (z, 0, MPFR_RNDZ); 540 541 /* simplest case right justified */ 542 check_sprintf (" 0xf.edcba987654321p+24", "%25Ra", x); 543 check_sprintf (" 0xf.edcba987654321p+24", "%25RUa", x); 544 check_sprintf (" 0xf.edcba987654321p+24", "%25RDa", x); 545 check_sprintf (" 0xf.edcba987654321p+24", "%25RYa", x); 546 check_sprintf (" 0xf.edcba987654321p+24", "%25RZa", x); 547 check_sprintf (" 0xf.edcba987654321p+24", "%25RNa", x); 548 check_sprintf (" 0x1p+28", "%25.0Ra", x); 549 check_sprintf (" 0x0p+0", "%25.0Ra", z); 550 /* sign or space, pad with leading zeros */ 551 check_sprintf (" 0X00F.EDCBA987654321P+24", "% 025RA", x); 552 check_sprintf (" 0X000000000000000001P+28", "% 025.0RA", x); 553 check_sprintf (" 0X0000000000000000000P+0", "% 025.0RA", z); 554 /* sign + or -, left justified */ 555 check_sprintf ("+0xf.edcba987654321p+24 ", "%+-25Ra", x); 556 check_sprintf ("+0x1p+28 ", "%+-25.0Ra", x); 557 check_sprintf ("+0x0p+0 ", "%+-25.0Ra", z); 558 /* decimal point, left justified, precision and rounding parameter */ 559 check_vsprintf ("0XF.FP+24 ", "%#-10.*R*A", 1, MPFR_RNDN, x); 560 check_vsprintf ("0X1.P+28 ", "%#-10.*R*A", 0, MPFR_RNDN, x); 561 check_vsprintf ("0X0.P+0 ", "%#-10.*R*A", 0, MPFR_RNDN, z); 562 /* sign or space */ 563 check_sprintf (" 0xf.eddp+24", "% .3RNa", x); 564 check_sprintf (" 0x1p+28", "% .0RNa", x); 565 /* sign + or -, decimal point, pad with leading zeros */ 566 check_sprintf ("+0X0F.EP+24", "%0+#11.1RZA", x); 567 check_sprintf ("+0X00F.P+24", "%0+#11.0RZA", x); 568 check_sprintf ("+0X000.0P+0", "%0+#11.1RZA", z); 569 /* pad with leading zero */ 570 check_sprintf ("0x0000f.edcba987654321p+24", "%026RDa", x); 571 check_sprintf ("0x0000000000000000000fp+24", "%026.0RDa", x); 572 /* sign or space, decimal point, left justified */ 573 check_sprintf (" 0XF.EP+24 " , "%- #11.1RDA", x); 574 check_sprintf (" 0XF.P+24 " , "%- #11.0RDA", x); 575 576 mpfr_mul_si (x, x, -1, MPFR_RNDD); 577 mpfr_mul_si (z, z, -1, MPFR_RNDD); 578 579 /* sign + or - */ 580 check_sprintf ("-0xf.ep+24", "%+10.1RUa", x); 581 check_sprintf (" -0xfp+24", "%+10.0RUa", x); 582 check_sprintf (" -0x0p+0", "%+10.0RUa", z); 583 584 /* rounding bit is zero */ 585 mpfr_set_str (x, "0xF.7", 16, MPFR_RNDN); 586 check_sprintf ("0XFP+0", "%.0RNA", x); 587 /* tie case in round to nearest mode */ 588 mpfr_set_str (x, "0x0.8800000000000000p+3", 16, MPFR_RNDN); 589 check_sprintf ("0x9.p-1", "%#.0RNa", x); 590 mpfr_set_str (x, "-0x0.9800000000000000p+3", 16, MPFR_RNDN); 591 check_sprintf ("-0xap-1", "%.0RNa", x); 592 /* trailing zeros in fractional part */ 593 check_sprintf ("-0X4.C0000000000000000000P+0", "%.20RNA", x); 594 /* rounding bit is one and the first non zero bit is far away */ 595 mpfr_set_prec (x, 1024); 596 mpfr_set_ui_2exp (x, 29, -1, MPFR_RNDN); 597 mpfr_nextabove (x); 598 check_sprintf ("0XFP+0", "%.0RNA", x); 599 600 /* with more than one limb */ 601 mpfr_set_prec (x, 300); 602 mpfr_set_str (x, "0xf.ffffffffffffffffffffffffffffffffffffffffffffffffffff" 603 "fffffffffffffffff", 16, MPFR_RNDN); 604 check_sprintf ("0x1p+4 [300]", "%.0RNa [300]", x); 605 check_sprintf ("0xfp+0 [300]", "%.0RZa [300]", x); 606 check_sprintf ("0x1p+4 [300]", "%.0RYa [300]", x); 607 check_sprintf ("0xfp+0 [300]", "%.0RDa [300]", x); 608 check_sprintf ("0x1p+4 [300]", "%.0RUa [300]", x); 609 check_sprintf ("0x1.0000000000000000000000000000000000000000p+4", 610 "%.40RNa", x); 611 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0", 612 "%.40RZa", x); 613 check_sprintf ("0x1.0000000000000000000000000000000000000000p+4", 614 "%.40RYa", x); 615 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0", 616 "%.40RDa", x); 617 check_sprintf ("0x1.0000000000000000000000000000000000000000p+4", 618 "%.40RUa", x); 619 620 mpfr_set_str (x, "0xf.7fffffffffffffffffffffffffffffffffffffffffffffffffff" 621 "ffffffffffffffffff", 16, MPFR_RNDN); 622 check_sprintf ("0XFP+0", "%.0RNA", x); 623 check_sprintf ("0XFP+0", "%.0RZA", x); 624 check_sprintf ("0X1P+4", "%.0RYA", x); 625 check_sprintf ("0XFP+0", "%.0RDA", x); 626 check_sprintf ("0X1P+4", "%.0RUA", x); 627 check_sprintf ("0XF.8P+0", "%.1RNA", x); 628 check_sprintf ("0XF.7P+0", "%.1RZA", x); 629 check_sprintf ("0XF.8P+0", "%.1RYA", x); 630 check_sprintf ("0XF.7P+0", "%.1RDA", x); 631 check_sprintf ("0XF.8P+0", "%.1RUA", x); 632 633 /* do not round up to the next power of the base */ 634 mpfr_set_str (x, "0xf.fffffffffffffffffffffffffffffffffffffeffffffffffffff" 635 "ffffffffffffffffff", 16, MPFR_RNDN); 636 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0", 637 "%.40RNa", x); 638 check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0", 639 "%.40RZa", x); 640 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0", 641 "%.40RYa", x); 642 check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0", 643 "%.40RDa", x); 644 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0", 645 "%.40RUa", x); 646 647 mpfr_clears (x, z, (mpfr_ptr) 0); 648 return 0; 649} 650 651static int 652binary (void) 653{ 654 mpfr_t x; 655 mpfr_t z; 656 mpfr_inits2 (64, x, z, (mpfr_ptr) 0); 657 658 /* special */ 659 mpfr_set_inf (x, 1); 660 check_sprintf (pinf_str, "%Rb", x); 661 662 mpfr_set_inf (x, -1); 663 check_sprintf (minf_str, "%Rb", x); 664 665 mpfr_set_nan (x); 666 check_sprintf (nan_str, "%Rb", x); 667 668 /* regular numbers */ 669 mpfr_set_str (x, "1110010101.1001101", 2, MPFR_RNDN); 670 mpfr_set_ui (z, 0, MPFR_RNDN); 671 672 /* simplest case: right justified */ 673 check_sprintf (" 1.1100101011001101p+9", "%25Rb", x); 674 check_sprintf (" 0p+0", "%25Rb", z); 675 /* sign or space, pad with leading zeros */ 676 check_sprintf (" 0001.1100101011001101p+9", "% 025Rb", x); 677 check_sprintf (" 000000000000000000000p+0", "% 025Rb", z); 678 /* sign + or -, left justified */ 679 check_sprintf ("+1.1100101011001101p+9 ", "%+-25Rb", x); 680 check_sprintf ("+0p+0 ", "%+-25Rb", z); 681 /* sign or space */ 682 check_sprintf (" 1.110p+9", "% .3RNb", x); 683 check_sprintf (" 1.1101p+9", "% .4RNb", x); 684 check_sprintf (" 0.0000p+0", "% .4RNb", z); 685 /* sign + or -, decimal point, pad with leading zeros */ 686 check_sprintf ("+00001.1p+9", "%0+#11.1RZb", x); 687 check_sprintf ("+0001.0p+10", "%0+#11.1RNb", x); 688 check_sprintf ("+000000.p+0", "%0+#11.0RNb", z); 689 /* pad with leading zero */ 690 check_sprintf ("00001.1100101011001101p+9", "%025RDb", x); 691 /* sign or space, decimal point (unused), left justified */ 692 check_sprintf (" 1.1p+9 ", "%- #11.1RDb", x); 693 check_sprintf (" 1.p+9 ", "%- #11.0RDb", x); 694 check_sprintf (" 1.p+10 ", "%- #11.0RUb", x); 695 check_sprintf (" 1.p+9 ", "%- #11.0RZb", x); 696 check_sprintf (" 1.p+10 ", "%- #11.0RYb", x); 697 check_sprintf (" 1.p+10 ", "%- #11.0RNb", x); 698 699 mpfr_mul_si (x, x, -1, MPFR_RNDD); 700 mpfr_mul_si (z, z, -1, MPFR_RNDD); 701 702 /* sign + or - */ 703 check_sprintf (" -1.1p+9", "%+10.1RUb", x); 704 check_sprintf (" -0.0p+0", "%+10.1RUb", z); 705 706 /* precision 0 */ 707 check_sprintf ("-1p+10", "%.0RNb", x); 708 check_sprintf ("-1p+10", "%.0RDb", x); 709 check_sprintf ("-1p+9", "%.0RUb", x); 710 check_sprintf ("-1p+9", "%.0RZb", x); 711 check_sprintf ("-1p+10", "%.0RYb", x); 712 /* round to next base power */ 713 check_sprintf ("-1.0p+10", "%.1RNb", x); 714 check_sprintf ("-1.0p+10", "%.1RDb", x); 715 check_sprintf ("-1.0p+10", "%.1RYb", x); 716 /* do not round to next base power */ 717 check_sprintf ("-1.1p+9", "%.1RUb", x); 718 check_sprintf ("-1.1p+9", "%.1RZb", x); 719 /* rounding bit is zero */ 720 check_sprintf ("-1.11p+9", "%.2RNb", x); 721 /* tie case in round to nearest mode */ 722 check_sprintf ("-1.1100101011001101p+9", "%.16RNb", x); 723 /* trailing zeros in fractional part */ 724 check_sprintf ("-1.110010101100110100000000000000p+9", "%.30RNb", x); 725 726 mpfr_clears (x, z, (mpfr_ptr) 0); 727 return 0; 728} 729 730static int 731mixed (void) 732{ 733 int n1; 734 int n2; 735 int i = 121; 736 long double d = 1. / 31.; 737 mpf_t mpf; 738 mpq_t mpq; 739 mpz_t mpz; 740 mpfr_t x; 741 mpfr_rnd_t rnd; 742 743 mpf_init (mpf); 744 mpf_set_ui (mpf, 40); 745 mpf_div_ui (mpf, mpf, 31); /* mpf = 40.0 / 31.0 */ 746 mpq_init (mpq); 747 mpq_set_ui (mpq, 123456, 4567890); 748 mpz_init (mpz); 749 mpz_fib_ui (mpz, 64); 750 mpfr_init (x); 751 mpfr_set_str (x, "-12345678.875", 10, MPFR_RNDN); 752 rnd = MPFR_RNDD; 753 754 check_vsprintf ("121%", "%i%%", i); 755 check_vsprintf ("121% -1.2345678875E+07", "%i%% %RNE", i, x); 756 check_vsprintf ("121, -12345679", "%i, %.0Rf", i, x); 757 check_vsprintf ("10610209857723, -1.2345678875e+07", "%Zi, %R*e", mpz, rnd, 758 x); 759 check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i); 760 check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq); 761 n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323", "%i, %.*Rf, %Ff%n", 762 i, 12, x, mpf, &n2); 763 if (n1 != n2) 764 { 765 printf ("error in number of characters written by mpfr_vsprintf\n"); 766 printf ("expected: %d\n", n2); 767 printf (" got: %d\n", n1); 768 exit (1); 769 } 770 771#ifndef NPRINTF_L 772 check_vsprintf ("00000010610209857723, -1.2345678875e+07, 0.032258", 773 "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d); 774#endif 775 776 mpf_clear (mpf); 777 mpq_clear (mpq); 778 mpz_clear (mpz); 779 mpfr_clear (x); 780 return 0; 781} 782 783/* Check with locale "da_DK". On most platforms, decimal point is ',' 784 and thousands separator is '.'; the test is not performed if this 785 is not the case or if the locale doesn't exist. */ 786static int 787locale_da_DK (void) 788{ 789 mpfr_prec_t p = 128; 790 mpfr_t x; 791 792 if (setlocale (LC_ALL, "da_DK") == 0 || 793 localeconv()->decimal_point[0] != ',' || 794 localeconv()->thousands_sep[0] != '.') 795 return 0; 796 797 mpfr_init2 (x, p); 798 799 /* positive numbers */ 800 mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN); 801 802 /* simplest case right justified with thousands separator */ 803 check_sprintf (" 1,899347461279296875e+07", "%'30Re", x); 804 check_sprintf (" 1,89935e+07", "%'30Rg", x); 805 check_sprintf (" 18.993.474,61279296875", "%'30.19Rg", x); 806 check_sprintf (" 18.993.474,612793", "%'30Rf", x); 807 808 /* sign or space, pad, thousands separator with leading zeros */ 809 check_sprintf (" 000001,899347461279296875E+07", "%' 030RE", x); 810 check_sprintf (" 0000000000000000001,89935E+07", "%' 030RG", x); 811 check_sprintf (" 000000018.993.474,61279296875", "%' 030.19RG", x); 812 check_sprintf (" 00000000000018.993.474,612793", "%' 030RF", x); 813 814 mpfr_set_ui (x, 50, MPFR_RNDN); 815 mpfr_exp10 (x, x, MPFR_RNDN); 816 check_sprintf ("100000000000000000000000000000000000000000000000000", "%.0Rf", 817 x); 818 check_sprintf 819 ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,", 820 "%'#.0Rf", x); 821 check_sprintf 822 ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,0000", 823 "%'.4Rf", x); 824 825 mpfr_clear (x); 826 return 0; 827} 828 829/* check concordance between mpfr_asprintf result with a regular mpfr float 830 and with a regular double float */ 831static int 832random_double (void) 833{ 834 mpfr_t x; /* random regular mpfr float */ 835 double y; /* regular double float (equal to x) */ 836 837 char flag[] = 838 { 839 '-', 840 '+', 841 ' ', 842 '#', 843 '0', /* no ambiguity: first zeros are flag zero*/ 844 '\'' 845 }; 846 /* no 'a': mpfr and glibc do not have the same semantic */ 847 char specifier[] = 848 { 849 'e', 850 'f', 851 'g', 852 'E', 853 'f', /* SUSv2 doesn't accept %F, but %F and %f are the same for 854 regular numbers */ 855 'G', 856 }; 857 int spec; /* random index in specifier[] */ 858 int prec; /* random value for precision field */ 859 860 /* in the format string for mpfr_t variable, the maximum length is 861 reached by something like "%-+ #0'.*Rf", that is 12 characters. */ 862#define FMT_MPFR_SIZE 12 863 char fmt_mpfr[FMT_MPFR_SIZE]; 864 char *ptr_mpfr; 865 866 /* in the format string for double variable, the maximum length is 867 reached by something like "%-+ #0'.*f", that is 11 characters. */ 868#define FMT_SIZE 11 869 char fmt[FMT_SIZE]; 870 char *ptr; 871 872 int xi; 873 char *xs; 874 int yi; 875 char *ys; 876 877 int i, j, jmax; 878 879 mpfr_init2 (x, MPFR_LDBL_MANT_DIG); 880 881 for (i = 0; i < 1000; ++i) 882 { 883 /* 1. random double */ 884 do 885 { 886 y = DBL_RAND (); 887 } 888#ifdef HAVE_DENORMS 889 while (0); 890#else 891 while (ABS(y) < DBL_MIN); 892#endif 893 894 if (randlimb () % 2 == 0) 895 y = -y; 896 897 mpfr_set_d (x, y, MPFR_RNDN); 898 if (y != mpfr_get_d (x, MPFR_RNDN)) 899 /* conversion error: skip this one */ 900 continue; 901 902 /* 2. build random format strings fmt_mpfr and fmt */ 903 ptr_mpfr = fmt_mpfr; 904 ptr = fmt; 905 *ptr_mpfr++ = *ptr++ = '%'; 906 /* random specifier 'e', 'f', 'g', 'E', 'F', or 'G' */ 907 spec = (int) (randlimb() % 6); 908 /* random flags, but no ' flag with %e */ 909 jmax = (spec == 0 || spec == 3) ? 5 : 6; 910 for (j = 0; j < jmax; j++) 911 { 912 if (randlimb() % 3 == 0) 913 *ptr_mpfr++ = *ptr++ = flag[j]; 914 } 915 *ptr_mpfr++ = *ptr++ = '.'; 916 *ptr_mpfr++ = *ptr++ = '*'; 917 *ptr_mpfr++ = 'R'; 918 *ptr_mpfr++ = *ptr++ = specifier[spec]; 919 *ptr_mpfr = *ptr = '\0'; 920 MPFR_ASSERTN (ptr - fmt < FMT_SIZE); 921 MPFR_ASSERTN (ptr_mpfr - fmt_mpfr < FMT_MPFR_SIZE); 922 923 /* advantage small precision */ 924 if (randlimb() % 2 == 0) 925 prec = (int) (randlimb() % 10); 926 else 927 prec = (int) (randlimb() % prec_max_printf); 928 929 /* 3. calls and checks */ 930 /* the double float case is handled by the libc asprintf through 931 gmp_asprintf */ 932 xi = mpfr_asprintf (&xs, fmt_mpfr, prec, x); 933 yi = mpfr_asprintf (&ys, fmt, prec, y); 934 935 /* test if XS and YS differ, beware that ISO C99 doesn't specify 936 the sign of a zero exponent (the C99 rationale says: "The sign 937 of a zero exponent in %e format is unspecified. The committee 938 knows of different implementations and choose not to require 939 implementations to document their behaviour in this case 940 (by making this be implementation defined behaviour). Most 941 implementations use a "+" sign, e.g., 1.2e+00; but there is at 942 least one implementation that uses the sign of the unlimited 943 precision result, e.g., the 0.987 would be 9.87e-01, so could 944 end up as 1e-00 after rounding to one digit of precision."), 945 while mpfr always uses '+' */ 946 if (xi != yi 947 || ((strcmp (xs, ys) != 0) 948 && (spec == 1 || spec == 4 949 || ((strstr (xs, "e+00") == NULL 950 || strstr (ys, "e-00") == NULL) 951 && (strstr (xs, "E+00") == NULL 952 || strstr (ys, "E-00") == NULL))))) 953 { 954 mpfr_printf ("Error in mpfr_asprintf(\"%s\", %d, %Re)\n", 955 fmt_mpfr, prec, x); 956 printf ("expected: %s\n", ys); 957 printf (" got: %s\n", xs); 958 printf ("xi=%d yi=%d spec=%d\n", xi, yi, spec); 959 960 exit (1); 961 } 962 963 mpfr_free_str (xs); 964 mpfr_free_str (ys); 965 } 966 967 mpfr_clear (x); 968 return 0; 969} 970 971static void 972bug20080610 (void) 973{ 974 /* bug on icc found on June 10, 2008 */ 975 /* this is not a bug but a different implementation choice: ISO C99 doesn't 976 specify the sign of a zero exponent (see note in random_double above). */ 977 mpfr_t x; 978 double y; 979 int xi; 980 char *xs; 981 int yi; 982 char *ys; 983 984 mpfr_init2 (x, MPFR_LDBL_MANT_DIG); 985 986 y = -9.95645044213728791504536275169812142849e-01; 987 mpfr_set_d (x, y, MPFR_RNDN); 988 989 xi = mpfr_asprintf (&xs, "%- #0.*Re", 1, x); 990 yi = mpfr_asprintf (&ys, "%- #0.*e", 1, y); 991 992 if (xi != yi || strcmp (xs, ys) != 0) 993 { 994 printf ("Error in bug20080610\n"); 995 printf ("expected: %s\n", ys); 996 printf (" got: %s\n", xs); 997 printf ("xi=%d yi=%d\n", xi, yi); 998 999 exit (1); 1000 } 1001 1002 mpfr_free_str (xs); 1003 mpfr_free_str (ys); 1004 mpfr_clear (x); 1005} 1006 1007static void 1008bug20081214 (void) 1009{ 1010 /* problem with glibc 2.3.6, December 14, 2008: 1011 the system asprintf outputs "-1.0" instead of "-1.". */ 1012 mpfr_t x; 1013 double y; 1014 int xi; 1015 char *xs; 1016 int yi; 1017 char *ys; 1018 1019 mpfr_init2 (x, MPFR_LDBL_MANT_DIG); 1020 1021 y = -9.90597761233942053494e-01; 1022 mpfr_set_d (x, y, MPFR_RNDN); 1023 1024 xi = mpfr_asprintf (&xs, "%- #0.*RG", 1, x); 1025 yi = mpfr_asprintf (&ys, "%- #0.*G", 1, y); 1026 1027 if (xi != yi || strcmp (xs, ys) != 0) 1028 { 1029 mpfr_printf ("Error in bug20081214\n" 1030 "mpfr_asprintf(\"%- #0.*Re\", 1, %Re)\n", x); 1031 printf ("expected: %s\n", ys); 1032 printf (" got: %s\n", xs); 1033 printf ("xi=%d yi=%d\n", xi, yi); 1034 1035 exit (1); 1036 } 1037 1038 mpfr_free_str (xs); 1039 mpfr_free_str (ys); 1040 mpfr_clear (x); 1041} 1042 1043/* In particular, the following test makes sure that the rounding 1044 * for %Ra and %Rb is not done on the MPFR number itself (as it 1045 * would overflow). Note: it has been reported on comp.std.c that 1046 * some C libraries behave differently on %a, but this is a bug. 1047 */ 1048static void 1049check_emax_aux (mpfr_exp_t e) 1050{ 1051 mpfr_t x; 1052 char *s1, s2[256]; 1053 int i; 1054 mpfr_exp_t emax; 1055 1056 MPFR_ASSERTN (e <= LONG_MAX); 1057 emax = mpfr_get_emax (); 1058 set_emax (e); 1059 1060 mpfr_init2 (x, 16); 1061 1062 mpfr_set_inf (x, 1); 1063 mpfr_nextbelow (x); 1064 1065 i = mpfr_asprintf (&s1, "%Ra %.2Ra", x, x); 1066 MPFR_ASSERTN (i > 0); 1067 1068 mpfr_snprintf (s2, 256, "0x7.fff8p+%ld 0x8.00p+%ld", e-3, e-3); 1069 1070 if (strcmp (s1, s2) != 0) 1071 { 1072 printf ("Error in check_emax_aux for emax = %ld\n", e); 1073 printf ("Expected %s\n", s2); 1074 printf ("Got %s\n", s1); 1075 exit (1); 1076 } 1077 1078 mpfr_free_str (s1); 1079 1080 i = mpfr_asprintf (&s1, "%Rb %.2Rb", x, x); 1081 MPFR_ASSERTN (i > 0); 1082 1083 mpfr_snprintf (s2, 256, "1.111111111111111p+%ld 1.00p+%ld", e-1, e); 1084 1085 if (strcmp (s1, s2) != 0) 1086 { 1087 printf ("Error in check_emax_aux for emax = %ld\n", e); 1088 printf ("Expected %s\n", s2); 1089 printf ("Got %s\n", s1); 1090 exit (1); 1091 } 1092 1093 mpfr_free_str (s1); 1094 1095 mpfr_clear (x); 1096 set_emax (emax); 1097} 1098 1099static void 1100check_emax (void) 1101{ 1102 check_emax_aux (15); 1103 check_emax_aux (MPFR_EMAX_MAX); 1104} 1105 1106int 1107main (int argc, char **argv) 1108{ 1109 char *locale; 1110 1111 tests_start_mpfr (); 1112 1113#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) 1114 /* currently, we just check with 'C' locale */ 1115 locale = setlocale (LC_ALL, "C"); 1116#endif 1117 1118 native_types (); 1119 hexadecimal (); 1120 binary (); 1121 decimal (); 1122 mixed (); 1123 check_emax (); 1124 1125#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) 1126 locale_da_DK (); 1127 1128 setlocale (LC_ALL, locale); 1129#endif 1130 1131 if (getenv ("MPFR_CHECK_LIBC_PRINTF")) 1132 { 1133 /* check against libc */ 1134 random_double (); 1135 bug20081214 (); 1136 bug20080610 (); 1137 } 1138 1139 tests_end_mpfr (); 1140 return 0; 1141} 1142 1143#else /* MPFR_VERSION */ 1144 1145int 1146main (void) 1147{ 1148 printf ("Warning! Test disabled for this MPFR version.\n"); 1149 return 0; 1150} 1151 1152#endif /* MPFR_VERSION */ 1153 1154#else /* HAVE_STDARG */ 1155 1156int 1157main (void) 1158{ 1159 /* We have nothing to test. */ 1160 return 0; 1161} 1162 1163#endif /* HAVE_STDARG */ 1164