1 /* Test of POSIX compatible vsnprintf() and snprintf() functions.
2 Copyright (C) 2007-2010 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007. */
19 #include "minus-zero.h"
22 /* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0. */
26 static double plus_zero = 0.0;
27 double minus_zero = minus_zerod;
28 return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
31 /* Representation of an 80-bit 'long double' as an initializer for a sequence
32 of 'unsigned int' words. */
33 #ifdef WORDS_BIGENDIAN
34 # define LDBL80_WORDS(exponent,manthi,mantlo) \
35 { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
36 ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
37 (unsigned int) (mantlo) << 16 \
40 # define LDBL80_WORDS(exponent,manthi,mantlo) \
41 { mantlo, manthi, exponent }
45 strmatch (const char *pattern, const char *string)
47 if (strlen (pattern) != strlen (string))
49 for (; *pattern != '\0'; pattern++, string++)
50 if (*pattern != '*' && *string != *pattern)
55 /* Test whether string[start_index..end_index-1] is a valid textual
56 representation of NaN. */
58 strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
60 if (start_index < end_index)
62 if (string[start_index] == '-')
64 if (start_index + 3 <= end_index
65 && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
68 if (start_index == end_index
69 || (string[start_index] == '(' && string[end_index - 1] == ')'))
77 test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
82 /* Test return value convention. */
84 for (size = 0; size <= 8; size++)
88 memcpy (buf, "DEADBEEF", 8);
89 retval = my_snprintf (buf, size, "%d", 12345);
95 ASSERT (memcmp (buf, "12345", size - 1) == 0);
96 ASSERT (buf[size - 1] == '\0');
98 ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
102 ASSERT (memcmp (buf, "12345\0EF", 8) == 0);
106 /* Test support of size specifiers as in C99. */
111 my_snprintf (result, sizeof (result), "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
112 ASSERT (strcmp (result, "12345671 33") == 0);
113 ASSERT (retval == strlen (result));
119 my_snprintf (result, sizeof (result), "%zu %d", (size_t) 12345672, 33, 44, 55);
120 ASSERT (strcmp (result, "12345672 33") == 0);
121 ASSERT (retval == strlen (result));
127 my_snprintf (result, sizeof (result), "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
128 ASSERT (strcmp (result, "12345673 33") == 0);
129 ASSERT (retval == strlen (result));
135 my_snprintf (result, sizeof (result), "%Lg %d", (long double) 1.5, 33, 44, 55);
136 ASSERT (strcmp (result, "1.5 33") == 0);
137 ASSERT (retval == strlen (result));
140 /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
141 output of floating-point numbers. */
143 { /* A positive number. */
146 my_snprintf (result, sizeof (result), "%a %d", 3.1416015625, 33, 44, 55);
147 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
148 || strcmp (result, "0x3.244p+0 33") == 0
149 || strcmp (result, "0x6.488p-1 33") == 0
150 || strcmp (result, "0xc.91p-2 33") == 0);
151 ASSERT (retval == strlen (result));
154 { /* A negative number. */
157 my_snprintf (result, sizeof (result), "%A %d", -3.1416015625, 33, 44, 55);
158 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
159 || strcmp (result, "-0X3.244P+0 33") == 0
160 || strcmp (result, "-0X6.488P-1 33") == 0
161 || strcmp (result, "-0XC.91P-2 33") == 0);
162 ASSERT (retval == strlen (result));
165 { /* Positive zero. */
168 my_snprintf (result, sizeof (result), "%a %d", 0.0, 33, 44, 55);
169 ASSERT (strcmp (result, "0x0p+0 33") == 0);
170 ASSERT (retval == strlen (result));
173 { /* Negative zero. */
176 my_snprintf (result, sizeof (result), "%a %d", minus_zerod, 33, 44, 55);
177 if (have_minus_zero ())
178 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
179 ASSERT (retval == strlen (result));
182 { /* Positive infinity. */
185 my_snprintf (result, sizeof (result), "%a %d", 1.0 / 0.0, 33, 44, 55);
186 ASSERT (strcmp (result, "inf 33") == 0);
187 ASSERT (retval == strlen (result));
190 { /* Negative infinity. */
193 my_snprintf (result, sizeof (result), "%a %d", -1.0 / 0.0, 33, 44, 55);
194 ASSERT (strcmp (result, "-inf 33") == 0);
195 ASSERT (retval == strlen (result));
201 my_snprintf (result, sizeof (result), "%a %d", NaNd (), 33, 44, 55);
202 ASSERT (strlen (result) >= 3 + 3
203 && strisnan (result, 0, strlen (result) - 3, 0)
204 && strcmp (result + strlen (result) - 3, " 33") == 0);
205 ASSERT (retval == strlen (result));
208 { /* Rounding near the decimal point. */
211 my_snprintf (result, sizeof (result), "%.0a %d", 1.5, 33, 44, 55);
212 ASSERT (strcmp (result, "0x2p+0 33") == 0
213 || strcmp (result, "0x3p-1 33") == 0
214 || strcmp (result, "0x6p-2 33") == 0
215 || strcmp (result, "0xcp-3 33") == 0);
216 ASSERT (retval == strlen (result));
219 { /* Rounding with precision 0. */
222 my_snprintf (result, sizeof (result), "%.0a %d", 1.51, 33, 44, 55);
223 ASSERT (strcmp (result, "0x2p+0 33") == 0
224 || strcmp (result, "0x3p-1 33") == 0
225 || strcmp (result, "0x6p-2 33") == 0
226 || strcmp (result, "0xcp-3 33") == 0);
227 ASSERT (retval == strlen (result));
230 { /* Rounding with precision 1. */
233 my_snprintf (result, sizeof (result), "%.1a %d", 1.51, 33, 44, 55);
234 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
235 || strcmp (result, "0x3.0p-1 33") == 0
236 || strcmp (result, "0x6.1p-2 33") == 0
237 || strcmp (result, "0xc.1p-3 33") == 0);
238 ASSERT (retval == strlen (result));
241 { /* Rounding with precision 2. */
244 my_snprintf (result, sizeof (result), "%.2a %d", 1.51, 33, 44, 55);
245 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
246 || strcmp (result, "0x3.05p-1 33") == 0
247 || strcmp (result, "0x6.0ap-2 33") == 0
248 || strcmp (result, "0xc.14p-3 33") == 0);
249 ASSERT (retval == strlen (result));
252 { /* Rounding with precision 3. */
255 my_snprintf (result, sizeof (result), "%.3a %d", 1.51, 33, 44, 55);
256 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
257 || strcmp (result, "0x3.052p-1 33") == 0
258 || strcmp (result, "0x6.0a4p-2 33") == 0
259 || strcmp (result, "0xc.148p-3 33") == 0);
260 ASSERT (retval == strlen (result));
263 { /* Rounding can turn a ...FFF into a ...000. */
266 my_snprintf (result, sizeof (result), "%.3a %d", 1.49999, 33, 44, 55);
267 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
268 || strcmp (result, "0x3.000p-1 33") == 0
269 || strcmp (result, "0x6.000p-2 33") == 0
270 || strcmp (result, "0xc.000p-3 33") == 0);
271 ASSERT (retval == strlen (result));
274 { /* Rounding can turn a ...FFF into a ...000.
275 This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
278 my_snprintf (result, sizeof (result), "%.1a %d", 1.999, 33, 44, 55);
279 ASSERT (strcmp (result, "0x1.0p+1 33") == 0
280 || strcmp (result, "0x2.0p+0 33") == 0
281 || strcmp (result, "0x4.0p-1 33") == 0
282 || strcmp (result, "0x8.0p-2 33") == 0);
283 ASSERT (retval == strlen (result));
289 my_snprintf (result, sizeof (result), "%10a %d", 1.75, 33, 44, 55);
290 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
291 || strcmp (result, " 0x3.8p-1 33") == 0
292 || strcmp (result, " 0x7p-2 33") == 0
293 || strcmp (result, " 0xep-3 33") == 0);
294 ASSERT (retval == strlen (result));
297 { /* Small precision. */
300 my_snprintf (result, sizeof (result), "%.10a %d", 1.75, 33, 44, 55);
301 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
302 || strcmp (result, "0x3.8000000000p-1 33") == 0
303 || strcmp (result, "0x7.0000000000p-2 33") == 0
304 || strcmp (result, "0xe.0000000000p-3 33") == 0);
305 ASSERT (retval == strlen (result));
308 { /* Large precision. */
311 my_snprintf (result, sizeof (result), "%.50a %d", 1.75, 33, 44, 55);
312 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
313 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
314 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
315 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
316 ASSERT (retval == strlen (result));
322 my_snprintf (result, sizeof (result), "%-10a %d", 1.75, 33, 44, 55);
323 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
324 || strcmp (result, "0x3.8p-1 33") == 0
325 || strcmp (result, "0x7p-2 33") == 0
326 || strcmp (result, "0xep-3 33") == 0);
327 ASSERT (retval == strlen (result));
330 { /* FLAG_SHOWSIGN. */
333 my_snprintf (result, sizeof (result), "%+a %d", 1.75, 33, 44, 55);
334 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
335 || strcmp (result, "+0x3.8p-1 33") == 0
336 || strcmp (result, "+0x7p-2 33") == 0
337 || strcmp (result, "+0xep-3 33") == 0);
338 ASSERT (retval == strlen (result));
344 my_snprintf (result, sizeof (result), "% a %d", 1.75, 33, 44, 55);
345 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
346 || strcmp (result, " 0x3.8p-1 33") == 0
347 || strcmp (result, " 0x7p-2 33") == 0
348 || strcmp (result, " 0xep-3 33") == 0);
349 ASSERT (retval == strlen (result));
355 my_snprintf (result, sizeof (result), "%#a %d", 1.75, 33, 44, 55);
356 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
357 || strcmp (result, "0x3.8p-1 33") == 0
358 || strcmp (result, "0x7.p-2 33") == 0
359 || strcmp (result, "0xe.p-3 33") == 0);
360 ASSERT (retval == strlen (result));
366 my_snprintf (result, sizeof (result), "%#a %d", 1.0, 33, 44, 55);
367 ASSERT (strcmp (result, "0x1.p+0 33") == 0
368 || strcmp (result, "0x2.p-1 33") == 0
369 || strcmp (result, "0x4.p-2 33") == 0
370 || strcmp (result, "0x8.p-3 33") == 0);
371 ASSERT (retval == strlen (result));
374 { /* FLAG_ZERO with finite number. */
377 my_snprintf (result, sizeof (result), "%010a %d", 1.75, 33, 44, 55);
378 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
379 || strcmp (result, "0x003.8p-1 33") == 0
380 || strcmp (result, "0x00007p-2 33") == 0
381 || strcmp (result, "0x0000ep-3 33") == 0);
382 ASSERT (retval == strlen (result));
385 { /* FLAG_ZERO with infinite number. */
388 my_snprintf (result, sizeof (result), "%010a %d", 1.0 / 0.0, 33, 44, 55);
389 /* "0000000inf 33" is not a valid result; see
390 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
391 ASSERT (strcmp (result, " inf 33") == 0);
392 ASSERT (retval == strlen (result));
395 { /* FLAG_ZERO with NaN. */
398 my_snprintf (result, sizeof (result), "%050a %d", NaNd (), 33, 44, 55);
399 /* "0000000nan 33" is not a valid result; see
400 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
401 ASSERT (strlen (result) == 50 + 3
402 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
403 && strcmp (result + strlen (result) - 3, " 33") == 0);
404 ASSERT (retval == strlen (result));
407 { /* A positive number. */
410 my_snprintf (result, sizeof (result), "%La %d", 3.1416015625L, 33, 44, 55);
411 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
412 || strcmp (result, "0x3.244p+0 33") == 0
413 || strcmp (result, "0x6.488p-1 33") == 0
414 || strcmp (result, "0xc.91p-2 33") == 0);
415 ASSERT (retval == strlen (result));
418 { /* A negative number. */
421 my_snprintf (result, sizeof (result), "%LA %d", -3.1416015625L, 33, 44, 55);
422 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
423 || strcmp (result, "-0X3.244P+0 33") == 0
424 || strcmp (result, "-0X6.488P-1 33") == 0
425 || strcmp (result, "-0XC.91P-2 33") == 0);
426 ASSERT (retval == strlen (result));
429 { /* Positive zero. */
432 my_snprintf (result, sizeof (result), "%La %d", 0.0L, 33, 44, 55);
433 ASSERT (strcmp (result, "0x0p+0 33") == 0);
434 ASSERT (retval == strlen (result));
437 { /* Negative zero. */
440 my_snprintf (result, sizeof (result), "%La %d", minus_zerol, 33, 44, 55);
441 if (have_minus_zero ())
442 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
443 ASSERT (retval == strlen (result));
446 { /* Positive infinity. */
449 my_snprintf (result, sizeof (result), "%La %d", 1.0L / 0.0L, 33, 44, 55);
450 ASSERT (strcmp (result, "inf 33") == 0);
451 ASSERT (retval == strlen (result));
454 { /* Negative infinity. */
457 my_snprintf (result, sizeof (result), "%La %d", -1.0L / 0.0L, 33, 44, 55);
458 ASSERT (strcmp (result, "-inf 33") == 0);
459 ASSERT (retval == strlen (result));
465 my_snprintf (result, sizeof (result), "%La %d", NaNl (), 33, 44, 55);
466 ASSERT (strlen (result) >= 3 + 3
467 && strisnan (result, 0, strlen (result) - 3, 0)
468 && strcmp (result + strlen (result) - 3, " 33") == 0);
469 ASSERT (retval == strlen (result));
471 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
473 static union { unsigned int word[4]; long double value; } x =
474 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
477 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
478 ASSERT (strlen (result) >= 3 + 3
479 && strisnan (result, 0, strlen (result) - 3, 0)
480 && strcmp (result + strlen (result) - 3, " 33") == 0);
481 ASSERT (retval == strlen (result));
484 /* Signalling NaN. */
485 static union { unsigned int word[4]; long double value; } x =
486 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
489 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
490 ASSERT (strlen (result) >= 3 + 3
491 && strisnan (result, 0, strlen (result) - 3, 0)
492 && strcmp (result + strlen (result) - 3, " 33") == 0);
493 ASSERT (retval == strlen (result));
495 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
496 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
497 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
498 Application Architecture.
499 Table 5-2 "Floating-Point Register Encodings"
500 Figure 5-6 "Memory to Floating-Point Register Data Translation"
503 static union { unsigned int word[4]; long double value; } x =
504 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
507 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
508 ASSERT (strlen (result) >= 3 + 3
509 && strisnan (result, 0, strlen (result) - 3, 0)
510 && strcmp (result + strlen (result) - 3, " 33") == 0);
511 ASSERT (retval == strlen (result));
513 { /* Pseudo-Infinity. */
514 static union { unsigned int word[4]; long double value; } x =
515 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
518 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
519 ASSERT (strlen (result) >= 3 + 3
520 && strisnan (result, 0, strlen (result) - 3, 0)
521 && strcmp (result + strlen (result) - 3, " 33") == 0);
522 ASSERT (retval == strlen (result));
525 static union { unsigned int word[4]; long double value; } x =
526 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
529 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
530 ASSERT (strlen (result) >= 3 + 3
531 && strisnan (result, 0, strlen (result) - 3, 0)
532 && strcmp (result + strlen (result) - 3, " 33") == 0);
533 ASSERT (retval == strlen (result));
535 { /* Unnormalized number. */
536 static union { unsigned int word[4]; long double value; } x =
537 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
540 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
541 ASSERT (strlen (result) >= 3 + 3
542 && strisnan (result, 0, strlen (result) - 3, 0)
543 && strcmp (result + strlen (result) - 3, " 33") == 0);
544 ASSERT (retval == strlen (result));
546 { /* Pseudo-Denormal. */
547 static union { unsigned int word[4]; long double value; } x =
548 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
551 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
552 ASSERT (strlen (result) >= 3 + 3
553 && strisnan (result, 0, strlen (result) - 3, 0)
554 && strcmp (result + strlen (result) - 3, " 33") == 0);
555 ASSERT (retval == strlen (result));
559 { /* Rounding near the decimal point. */
562 my_snprintf (result, sizeof (result), "%.0La %d", 1.5L, 33, 44, 55);
563 ASSERT (strcmp (result, "0x2p+0 33") == 0
564 || strcmp (result, "0x3p-1 33") == 0
565 || strcmp (result, "0x6p-2 33") == 0
566 || strcmp (result, "0xcp-3 33") == 0);
567 ASSERT (retval == strlen (result));
570 { /* Rounding with precision 0. */
573 my_snprintf (result, sizeof (result), "%.0La %d", 1.51L, 33, 44, 55);
574 ASSERT (strcmp (result, "0x2p+0 33") == 0
575 || strcmp (result, "0x3p-1 33") == 0
576 || strcmp (result, "0x6p-2 33") == 0
577 || strcmp (result, "0xcp-3 33") == 0);
578 ASSERT (retval == strlen (result));
581 { /* Rounding with precision 1. */
584 my_snprintf (result, sizeof (result), "%.1La %d", 1.51L, 33, 44, 55);
585 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
586 || strcmp (result, "0x3.0p-1 33") == 0
587 || strcmp (result, "0x6.1p-2 33") == 0
588 || strcmp (result, "0xc.1p-3 33") == 0);
589 ASSERT (retval == strlen (result));
592 { /* Rounding with precision 2. */
595 my_snprintf (result, sizeof (result), "%.2La %d", 1.51L, 33, 44, 55);
596 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
597 || strcmp (result, "0x3.05p-1 33") == 0
598 || strcmp (result, "0x6.0ap-2 33") == 0
599 || strcmp (result, "0xc.14p-3 33") == 0);
600 ASSERT (retval == strlen (result));
603 { /* Rounding with precision 3. */
606 my_snprintf (result, sizeof (result), "%.3La %d", 1.51L, 33, 44, 55);
607 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
608 || strcmp (result, "0x3.052p-1 33") == 0
609 || strcmp (result, "0x6.0a4p-2 33") == 0
610 || strcmp (result, "0xc.148p-3 33") == 0);
611 ASSERT (retval == strlen (result));
614 { /* Rounding can turn a ...FFF into a ...000. */
617 my_snprintf (result, sizeof (result), "%.3La %d", 1.49999L, 33, 44, 55);
618 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
619 || strcmp (result, "0x3.000p-1 33") == 0
620 || strcmp (result, "0x6.000p-2 33") == 0
621 || strcmp (result, "0xc.000p-3 33") == 0);
622 ASSERT (retval == strlen (result));
625 { /* Rounding can turn a ...FFF into a ...000.
626 This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
627 glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
630 my_snprintf (result, sizeof (result), "%.1La %d", 1.999L, 33, 44, 55);
631 ASSERT (strcmp (result, "0x1.0p+1 33") == 0
632 || strcmp (result, "0x2.0p+0 33") == 0
633 || strcmp (result, "0x4.0p-1 33") == 0
634 || strcmp (result, "0x8.0p-2 33") == 0);
635 ASSERT (retval == strlen (result));
641 my_snprintf (result, sizeof (result), "%10La %d", 1.75L, 33, 44, 55);
642 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
643 || strcmp (result, " 0x3.8p-1 33") == 0
644 || strcmp (result, " 0x7p-2 33") == 0
645 || strcmp (result, " 0xep-3 33") == 0);
646 ASSERT (retval == strlen (result));
649 { /* Small precision. */
652 my_snprintf (result, sizeof (result), "%.10La %d", 1.75L, 33, 44, 55);
653 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
654 || strcmp (result, "0x3.8000000000p-1 33") == 0
655 || strcmp (result, "0x7.0000000000p-2 33") == 0
656 || strcmp (result, "0xe.0000000000p-3 33") == 0);
657 ASSERT (retval == strlen (result));
660 { /* Large precision. */
663 my_snprintf (result, sizeof (result), "%.50La %d", 1.75L, 33, 44, 55);
664 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
665 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
666 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
667 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
668 ASSERT (retval == strlen (result));
674 my_snprintf (result, sizeof (result), "%-10La %d", 1.75L, 33, 44, 55);
675 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
676 || strcmp (result, "0x3.8p-1 33") == 0
677 || strcmp (result, "0x7p-2 33") == 0
678 || strcmp (result, "0xep-3 33") == 0);
679 ASSERT (retval == strlen (result));
682 { /* FLAG_SHOWSIGN. */
685 my_snprintf (result, sizeof (result), "%+La %d", 1.75L, 33, 44, 55);
686 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
687 || strcmp (result, "+0x3.8p-1 33") == 0
688 || strcmp (result, "+0x7p-2 33") == 0
689 || strcmp (result, "+0xep-3 33") == 0);
690 ASSERT (retval == strlen (result));
696 my_snprintf (result, sizeof (result), "% La %d", 1.75L, 33, 44, 55);
697 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
698 || strcmp (result, " 0x3.8p-1 33") == 0
699 || strcmp (result, " 0x7p-2 33") == 0
700 || strcmp (result, " 0xep-3 33") == 0);
701 ASSERT (retval == strlen (result));
707 my_snprintf (result, sizeof (result), "%#La %d", 1.75L, 33, 44, 55);
708 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
709 || strcmp (result, "0x3.8p-1 33") == 0
710 || strcmp (result, "0x7.p-2 33") == 0
711 || strcmp (result, "0xe.p-3 33") == 0);
712 ASSERT (retval == strlen (result));
718 my_snprintf (result, sizeof (result), "%#La %d", 1.0L, 33, 44, 55);
719 ASSERT (strcmp (result, "0x1.p+0 33") == 0
720 || strcmp (result, "0x2.p-1 33") == 0
721 || strcmp (result, "0x4.p-2 33") == 0
722 || strcmp (result, "0x8.p-3 33") == 0);
723 ASSERT (retval == strlen (result));
726 { /* FLAG_ZERO with finite number. */
729 my_snprintf (result, sizeof (result), "%010La %d", 1.75L, 33, 44, 55);
730 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
731 || strcmp (result, "0x003.8p-1 33") == 0
732 || strcmp (result, "0x00007p-2 33") == 0
733 || strcmp (result, "0x0000ep-3 33") == 0);
734 ASSERT (retval == strlen (result));
737 { /* FLAG_ZERO with infinite number. */
740 my_snprintf (result, sizeof (result), "%010La %d", 1.0L / 0.0L, 33, 44, 55);
741 /* "0000000inf 33" is not a valid result; see
742 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
743 ASSERT (strcmp (result, " inf 33") == 0);
744 ASSERT (retval == strlen (result));
747 { /* FLAG_ZERO with NaN. */
750 my_snprintf (result, sizeof (result), "%050La %d", NaNl (), 33, 44, 55);
751 /* "0000000nan 33" is not a valid result; see
752 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
753 ASSERT (strlen (result) == 50 + 3
754 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
755 && strcmp (result + strlen (result) - 3, " 33") == 0);
756 ASSERT (retval == strlen (result));
759 /* Test the support of the %f format directive. */
761 { /* A positive number. */
764 my_snprintf (result, sizeof (result), "%f %d", 12.75, 33, 44, 55);
765 ASSERT (strcmp (result, "12.750000 33") == 0);
766 ASSERT (retval == strlen (result));
769 { /* A larger positive number. */
772 my_snprintf (result, sizeof (result), "%f %d", 1234567.0, 33, 44, 55);
773 ASSERT (strcmp (result, "1234567.000000 33") == 0);
774 ASSERT (retval == strlen (result));
777 { /* Small and large positive numbers. */
778 static struct { double value; const char *string; } data[] =
780 { 1.234321234321234e-37, "0.000000" },
781 { 1.234321234321234e-36, "0.000000" },
782 { 1.234321234321234e-35, "0.000000" },
783 { 1.234321234321234e-34, "0.000000" },
784 { 1.234321234321234e-33, "0.000000" },
785 { 1.234321234321234e-32, "0.000000" },
786 { 1.234321234321234e-31, "0.000000" },
787 { 1.234321234321234e-30, "0.000000" },
788 { 1.234321234321234e-29, "0.000000" },
789 { 1.234321234321234e-28, "0.000000" },
790 { 1.234321234321234e-27, "0.000000" },
791 { 1.234321234321234e-26, "0.000000" },
792 { 1.234321234321234e-25, "0.000000" },
793 { 1.234321234321234e-24, "0.000000" },
794 { 1.234321234321234e-23, "0.000000" },
795 { 1.234321234321234e-22, "0.000000" },
796 { 1.234321234321234e-21, "0.000000" },
797 { 1.234321234321234e-20, "0.000000" },
798 { 1.234321234321234e-19, "0.000000" },
799 { 1.234321234321234e-18, "0.000000" },
800 { 1.234321234321234e-17, "0.000000" },
801 { 1.234321234321234e-16, "0.000000" },
802 { 1.234321234321234e-15, "0.000000" },
803 { 1.234321234321234e-14, "0.000000" },
804 { 1.234321234321234e-13, "0.000000" },
805 { 1.234321234321234e-12, "0.000000" },
806 { 1.234321234321234e-11, "0.000000" },
807 { 1.234321234321234e-10, "0.000000" },
808 { 1.234321234321234e-9, "0.000000" },
809 { 1.234321234321234e-8, "0.000000" },
810 { 1.234321234321234e-7, "0.000000" },
811 { 1.234321234321234e-6, "0.000001" },
812 { 1.234321234321234e-5, "0.000012" },
813 { 1.234321234321234e-4, "0.000123" },
814 { 1.234321234321234e-3, "0.001234" },
815 { 1.234321234321234e-2, "0.012343" },
816 { 1.234321234321234e-1, "0.123432" },
817 { 1.234321234321234, "1.234321" },
818 { 1.234321234321234e1, "12.343212" },
819 { 1.234321234321234e2, "123.432123" },
820 { 1.234321234321234e3, "1234.321234" },
821 { 1.234321234321234e4, "12343.212343" },
822 { 1.234321234321234e5, "123432.123432" },
823 { 1.234321234321234e6, "1234321.234321" },
824 { 1.234321234321234e7, "12343212.343212" },
825 { 1.234321234321234e8, "123432123.432123" },
826 { 1.234321234321234e9, "1234321234.321234" },
827 { 1.234321234321234e10, "12343212343.2123**" },
828 { 1.234321234321234e11, "123432123432.123***" },
829 { 1.234321234321234e12, "1234321234321.23****" },
830 { 1.234321234321234e13, "12343212343212.3*****" },
831 { 1.234321234321234e14, "123432123432123.******" },
832 { 1.234321234321234e15, "1234321234321234.000000" },
833 { 1.234321234321234e16, "123432123432123**.000000" },
834 { 1.234321234321234e17, "123432123432123***.000000" },
835 { 1.234321234321234e18, "123432123432123****.000000" },
836 { 1.234321234321234e19, "123432123432123*****.000000" },
837 { 1.234321234321234e20, "123432123432123******.000000" },
838 { 1.234321234321234e21, "123432123432123*******.000000" },
839 { 1.234321234321234e22, "123432123432123********.000000" },
840 { 1.234321234321234e23, "123432123432123*********.000000" },
841 { 1.234321234321234e24, "123432123432123**********.000000" },
842 { 1.234321234321234e25, "123432123432123***********.000000" },
843 { 1.234321234321234e26, "123432123432123************.000000" },
844 { 1.234321234321234e27, "123432123432123*************.000000" },
845 { 1.234321234321234e28, "123432123432123**************.000000" },
846 { 1.234321234321234e29, "123432123432123***************.000000" },
847 { 1.234321234321234e30, "123432123432123****************.000000" },
848 { 1.234321234321234e31, "123432123432123*****************.000000" },
849 { 1.234321234321234e32, "123432123432123******************.000000" },
850 { 1.234321234321234e33, "123432123432123*******************.000000" },
851 { 1.234321234321234e34, "123432123432123********************.000000" },
852 { 1.234321234321234e35, "123432123432123*********************.000000" },
853 { 1.234321234321234e36, "123432123432123**********************.000000" }
856 for (k = 0; k < SIZEOF (data); k++)
860 my_snprintf (result, sizeof (result), "%f", data[k].value);
861 ASSERT (strmatch (data[k].string, result));
862 ASSERT (retval == strlen (result));
866 { /* A negative number. */
869 my_snprintf (result, sizeof (result), "%f %d", -0.03125, 33, 44, 55);
870 ASSERT (strcmp (result, "-0.031250 33") == 0);
871 ASSERT (retval == strlen (result));
874 { /* Positive zero. */
877 my_snprintf (result, sizeof (result), "%f %d", 0.0, 33, 44, 55);
878 ASSERT (strcmp (result, "0.000000 33") == 0);
879 ASSERT (retval == strlen (result));
882 { /* Negative zero. */
885 my_snprintf (result, sizeof (result), "%f %d", minus_zerod, 33, 44, 55);
886 if (have_minus_zero ())
887 ASSERT (strcmp (result, "-0.000000 33") == 0);
888 ASSERT (retval == strlen (result));
891 { /* Positive infinity. */
894 my_snprintf (result, sizeof (result), "%f %d", 1.0 / 0.0, 33, 44, 55);
895 ASSERT (strcmp (result, "inf 33") == 0
896 || strcmp (result, "infinity 33") == 0);
897 ASSERT (retval == strlen (result));
900 { /* Negative infinity. */
903 my_snprintf (result, sizeof (result), "%f %d", -1.0 / 0.0, 33, 44, 55);
904 ASSERT (strcmp (result, "-inf 33") == 0
905 || strcmp (result, "-infinity 33") == 0);
906 ASSERT (retval == strlen (result));
912 my_snprintf (result, sizeof (result), "%f %d", NaNd (), 33, 44, 55);
913 ASSERT (strlen (result) >= 3 + 3
914 && strisnan (result, 0, strlen (result) - 3, 0)
915 && strcmp (result + strlen (result) - 3, " 33") == 0);
916 ASSERT (retval == strlen (result));
922 my_snprintf (result, sizeof (result), "%10f %d", 1.75, 33, 44, 55);
923 ASSERT (strcmp (result, " 1.750000 33") == 0);
924 ASSERT (retval == strlen (result));
930 my_snprintf (result, sizeof (result), "%-10f %d", 1.75, 33, 44, 55);
931 ASSERT (strcmp (result, "1.750000 33") == 0);
932 ASSERT (retval == strlen (result));
935 { /* FLAG_SHOWSIGN. */
938 my_snprintf (result, sizeof (result), "%+f %d", 1.75, 33, 44, 55);
939 ASSERT (strcmp (result, "+1.750000 33") == 0);
940 ASSERT (retval == strlen (result));
946 my_snprintf (result, sizeof (result), "% f %d", 1.75, 33, 44, 55);
947 ASSERT (strcmp (result, " 1.750000 33") == 0);
948 ASSERT (retval == strlen (result));
954 my_snprintf (result, sizeof (result), "%#f %d", 1.75, 33, 44, 55);
955 ASSERT (strcmp (result, "1.750000 33") == 0);
956 ASSERT (retval == strlen (result));
962 my_snprintf (result, sizeof (result), "%#.f %d", 1.75, 33, 44, 55);
963 ASSERT (strcmp (result, "2. 33") == 0);
964 ASSERT (retval == strlen (result));
967 { /* FLAG_ZERO with finite number. */
970 my_snprintf (result, sizeof (result), "%015f %d", 1234.0, 33, 44, 55);
971 ASSERT (strcmp (result, "00001234.000000 33") == 0);
972 ASSERT (retval == strlen (result));
975 { /* FLAG_ZERO with infinite number. */
978 my_snprintf (result, sizeof (result), "%015f %d", -1.0 / 0.0, 33, 44, 55);
979 ASSERT (strcmp (result, " -inf 33") == 0
980 || strcmp (result, " -infinity 33") == 0);
981 ASSERT (retval == strlen (result));
984 { /* FLAG_ZERO with NaN. */
987 my_snprintf (result, sizeof (result), "%050f %d", NaNd (), 33, 44, 55);
988 ASSERT (strlen (result) == 50 + 3
989 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
990 && strcmp (result + strlen (result) - 3, " 33") == 0);
991 ASSERT (retval == strlen (result));
997 my_snprintf (result, sizeof (result), "%.f %d", 1234.0, 33, 44, 55);
998 ASSERT (strcmp (result, "1234 33") == 0);
999 ASSERT (retval == strlen (result));
1002 { /* Precision with no rounding. */
1005 my_snprintf (result, sizeof (result), "%.2f %d", 999.951, 33, 44, 55);
1006 ASSERT (strcmp (result, "999.95 33") == 0);
1007 ASSERT (retval == strlen (result));
1010 { /* Precision with rounding. */
1013 my_snprintf (result, sizeof (result), "%.2f %d", 999.996, 33, 44, 55);
1014 ASSERT (strcmp (result, "1000.00 33") == 0);
1015 ASSERT (retval == strlen (result));
1018 { /* A positive number. */
1021 my_snprintf (result, sizeof (result), "%Lf %d", 12.75L, 33, 44, 55);
1022 ASSERT (strcmp (result, "12.750000 33") == 0);
1023 ASSERT (retval == strlen (result));
1026 { /* A larger positive number. */
1029 my_snprintf (result, sizeof (result), "%Lf %d", 1234567.0L, 33, 44, 55);
1030 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1031 ASSERT (retval == strlen (result));
1034 { /* Small and large positive numbers. */
1035 static struct { long double value; const char *string; } data[] =
1037 { 1.234321234321234e-37L, "0.000000" },
1038 { 1.234321234321234e-36L, "0.000000" },
1039 { 1.234321234321234e-35L, "0.000000" },
1040 { 1.234321234321234e-34L, "0.000000" },
1041 { 1.234321234321234e-33L, "0.000000" },
1042 { 1.234321234321234e-32L, "0.000000" },
1043 { 1.234321234321234e-31L, "0.000000" },
1044 { 1.234321234321234e-30L, "0.000000" },
1045 { 1.234321234321234e-29L, "0.000000" },
1046 { 1.234321234321234e-28L, "0.000000" },
1047 { 1.234321234321234e-27L, "0.000000" },
1048 { 1.234321234321234e-26L, "0.000000" },
1049 { 1.234321234321234e-25L, "0.000000" },
1050 { 1.234321234321234e-24L, "0.000000" },
1051 { 1.234321234321234e-23L, "0.000000" },
1052 { 1.234321234321234e-22L, "0.000000" },
1053 { 1.234321234321234e-21L, "0.000000" },
1054 { 1.234321234321234e-20L, "0.000000" },
1055 { 1.234321234321234e-19L, "0.000000" },
1056 { 1.234321234321234e-18L, "0.000000" },
1057 { 1.234321234321234e-17L, "0.000000" },
1058 { 1.234321234321234e-16L, "0.000000" },
1059 { 1.234321234321234e-15L, "0.000000" },
1060 { 1.234321234321234e-14L, "0.000000" },
1061 { 1.234321234321234e-13L, "0.000000" },
1062 { 1.234321234321234e-12L, "0.000000" },
1063 { 1.234321234321234e-11L, "0.000000" },
1064 { 1.234321234321234e-10L, "0.000000" },
1065 { 1.234321234321234e-9L, "0.000000" },
1066 { 1.234321234321234e-8L, "0.000000" },
1067 { 1.234321234321234e-7L, "0.000000" },
1068 { 1.234321234321234e-6L, "0.000001" },
1069 { 1.234321234321234e-5L, "0.000012" },
1070 { 1.234321234321234e-4L, "0.000123" },
1071 { 1.234321234321234e-3L, "0.001234" },
1072 { 1.234321234321234e-2L, "0.012343" },
1073 { 1.234321234321234e-1L, "0.123432" },
1074 { 1.234321234321234L, "1.234321" },
1075 { 1.234321234321234e1L, "12.343212" },
1076 { 1.234321234321234e2L, "123.432123" },
1077 { 1.234321234321234e3L, "1234.321234" },
1078 { 1.234321234321234e4L, "12343.212343" },
1079 { 1.234321234321234e5L, "123432.123432" },
1080 { 1.234321234321234e6L, "1234321.234321" },
1081 { 1.234321234321234e7L, "12343212.343212" },
1082 { 1.234321234321234e8L, "123432123.432123" },
1083 { 1.234321234321234e9L, "1234321234.321234" },
1084 { 1.234321234321234e10L, "12343212343.2123**" },
1085 { 1.234321234321234e11L, "123432123432.123***" },
1086 { 1.234321234321234e12L, "1234321234321.23****" },
1087 { 1.234321234321234e13L, "12343212343212.3*****" },
1088 { 1.234321234321234e14L, "123432123432123.******" },
1089 { 1.234321234321234e15L, "1234321234321234.000000" },
1090 { 1.234321234321234e16L, "123432123432123**.000000" },
1091 { 1.234321234321234e17L, "123432123432123***.000000" },
1092 { 1.234321234321234e18L, "123432123432123****.000000" },
1093 { 1.234321234321234e19L, "123432123432123*****.000000" },
1094 { 1.234321234321234e20L, "123432123432123******.000000" },
1095 { 1.234321234321234e21L, "123432123432123*******.000000" },
1096 { 1.234321234321234e22L, "123432123432123********.000000" },
1097 { 1.234321234321234e23L, "123432123432123*********.000000" },
1098 { 1.234321234321234e24L, "123432123432123**********.000000" },
1099 { 1.234321234321234e25L, "123432123432123***********.000000" },
1100 { 1.234321234321234e26L, "123432123432123************.000000" },
1101 { 1.234321234321234e27L, "123432123432123*************.000000" },
1102 { 1.234321234321234e28L, "123432123432123**************.000000" },
1103 { 1.234321234321234e29L, "123432123432123***************.000000" },
1104 { 1.234321234321234e30L, "123432123432123****************.000000" },
1105 { 1.234321234321234e31L, "123432123432123*****************.000000" },
1106 { 1.234321234321234e32L, "123432123432123******************.000000" },
1107 { 1.234321234321234e33L, "123432123432123*******************.000000" },
1108 { 1.234321234321234e34L, "123432123432123********************.000000" },
1109 { 1.234321234321234e35L, "123432123432123*********************.000000" },
1110 { 1.234321234321234e36L, "123432123432123**********************.000000" }
1113 for (k = 0; k < SIZEOF (data); k++)
1117 my_snprintf (result, sizeof (result), "%Lf", data[k].value);
1118 ASSERT (strmatch (data[k].string, result));
1119 ASSERT (retval == strlen (result));
1123 { /* A negative number. */
1126 my_snprintf (result, sizeof (result), "%Lf %d", -0.03125L, 33, 44, 55);
1127 ASSERT (strcmp (result, "-0.031250 33") == 0);
1128 ASSERT (retval == strlen (result));
1131 { /* Positive zero. */
1134 my_snprintf (result, sizeof (result), "%Lf %d", 0.0L, 33, 44, 55);
1135 ASSERT (strcmp (result, "0.000000 33") == 0);
1136 ASSERT (retval == strlen (result));
1139 { /* Negative zero. */
1142 my_snprintf (result, sizeof (result), "%Lf %d", minus_zerol, 33, 44, 55);
1143 if (have_minus_zero ())
1144 ASSERT (strcmp (result, "-0.000000 33") == 0);
1145 ASSERT (retval == strlen (result));
1148 { /* Positive infinity. */
1151 my_snprintf (result, sizeof (result), "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
1152 ASSERT (strcmp (result, "inf 33") == 0
1153 || strcmp (result, "infinity 33") == 0);
1154 ASSERT (retval == strlen (result));
1157 { /* Negative infinity. */
1160 my_snprintf (result, sizeof (result), "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
1161 ASSERT (strcmp (result, "-inf 33") == 0
1162 || strcmp (result, "-infinity 33") == 0);
1163 ASSERT (retval == strlen (result));
1169 my_snprintf (result, sizeof (result), "%Lf %d", NaNl (), 33, 44, 55);
1170 ASSERT (strlen (result) >= 3 + 3
1171 && strisnan (result, 0, strlen (result) - 3, 0)
1172 && strcmp (result + strlen (result) - 3, " 33") == 0);
1173 ASSERT (retval == strlen (result));
1175 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
1177 static union { unsigned int word[4]; long double value; } x =
1178 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
1181 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1182 ASSERT (strlen (result) >= 3 + 3
1183 && strisnan (result, 0, strlen (result) - 3, 0)
1184 && strcmp (result + strlen (result) - 3, " 33") == 0);
1185 ASSERT (retval == strlen (result));
1188 /* Signalling NaN. */
1189 static union { unsigned int word[4]; long double value; } x =
1190 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
1193 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1194 ASSERT (strlen (result) >= 3 + 3
1195 && strisnan (result, 0, strlen (result) - 3, 0)
1196 && strcmp (result + strlen (result) - 3, " 33") == 0);
1197 ASSERT (retval == strlen (result));
1199 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
1200 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
1201 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
1202 Application Architecture.
1203 Table 5-2 "Floating-Point Register Encodings"
1204 Figure 5-6 "Memory to Floating-Point Register Data Translation"
1207 static union { unsigned int word[4]; long double value; } x =
1208 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
1211 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1212 ASSERT (strlen (result) >= 3 + 3
1213 && strisnan (result, 0, strlen (result) - 3, 0)
1214 && strcmp (result + strlen (result) - 3, " 33") == 0);
1215 ASSERT (retval == strlen (result));
1217 { /* Pseudo-Infinity. */
1218 static union { unsigned int word[4]; long double value; } x =
1219 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
1222 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1223 ASSERT (strlen (result) >= 3 + 3
1224 && strisnan (result, 0, strlen (result) - 3, 0)
1225 && strcmp (result + strlen (result) - 3, " 33") == 0);
1226 ASSERT (retval == strlen (result));
1228 { /* Pseudo-Zero. */
1229 static union { unsigned int word[4]; long double value; } x =
1230 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
1233 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1234 ASSERT (strlen (result) >= 3 + 3
1235 && strisnan (result, 0, strlen (result) - 3, 0)
1236 && strcmp (result + strlen (result) - 3, " 33") == 0);
1237 ASSERT (retval == strlen (result));
1239 { /* Unnormalized number. */
1240 static union { unsigned int word[4]; long double value; } x =
1241 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
1244 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1245 ASSERT (strlen (result) >= 3 + 3
1246 && strisnan (result, 0, strlen (result) - 3, 0)
1247 && strcmp (result + strlen (result) - 3, " 33") == 0);
1248 ASSERT (retval == strlen (result));
1250 { /* Pseudo-Denormal. */
1251 static union { unsigned int word[4]; long double value; } x =
1252 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
1255 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1256 ASSERT (strlen (result) >= 3 + 3
1257 && strisnan (result, 0, strlen (result) - 3, 0)
1258 && strcmp (result + strlen (result) - 3, " 33") == 0);
1259 ASSERT (retval == strlen (result));
1266 my_snprintf (result, sizeof (result), "%10Lf %d", 1.75L, 33, 44, 55);
1267 ASSERT (strcmp (result, " 1.750000 33") == 0);
1268 ASSERT (retval == strlen (result));
1274 my_snprintf (result, sizeof (result), "%-10Lf %d", 1.75L, 33, 44, 55);
1275 ASSERT (strcmp (result, "1.750000 33") == 0);
1276 ASSERT (retval == strlen (result));
1279 { /* FLAG_SHOWSIGN. */
1282 my_snprintf (result, sizeof (result), "%+Lf %d", 1.75L, 33, 44, 55);
1283 ASSERT (strcmp (result, "+1.750000 33") == 0);
1284 ASSERT (retval == strlen (result));
1290 my_snprintf (result, sizeof (result), "% Lf %d", 1.75L, 33, 44, 55);
1291 ASSERT (strcmp (result, " 1.750000 33") == 0);
1292 ASSERT (retval == strlen (result));
1298 my_snprintf (result, sizeof (result), "%#Lf %d", 1.75L, 33, 44, 55);
1299 ASSERT (strcmp (result, "1.750000 33") == 0);
1300 ASSERT (retval == strlen (result));
1306 my_snprintf (result, sizeof (result), "%#.Lf %d", 1.75L, 33, 44, 55);
1307 ASSERT (strcmp (result, "2. 33") == 0);
1308 ASSERT (retval == strlen (result));
1311 { /* FLAG_ZERO with finite number. */
1314 my_snprintf (result, sizeof (result), "%015Lf %d", 1234.0L, 33, 44, 55);
1315 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1316 ASSERT (retval == strlen (result));
1319 { /* FLAG_ZERO with infinite number. */
1322 my_snprintf (result, sizeof (result), "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
1323 ASSERT (strcmp (result, " -inf 33") == 0
1324 || strcmp (result, " -infinity 33") == 0);
1325 ASSERT (retval == strlen (result));
1328 { /* FLAG_ZERO with NaN. */
1331 my_snprintf (result, sizeof (result), "%050Lf %d", NaNl (), 33, 44, 55);
1332 ASSERT (strlen (result) == 50 + 3
1333 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1334 && strcmp (result + strlen (result) - 3, " 33") == 0);
1335 ASSERT (retval == strlen (result));
1341 my_snprintf (result, sizeof (result), "%.Lf %d", 1234.0L, 33, 44, 55);
1342 ASSERT (strcmp (result, "1234 33") == 0);
1343 ASSERT (retval == strlen (result));
1346 { /* Precision with no rounding. */
1349 my_snprintf (result, sizeof (result), "%.2Lf %d", 999.951L, 33, 44, 55);
1350 ASSERT (strcmp (result, "999.95 33") == 0);
1351 ASSERT (retval == strlen (result));
1354 { /* Precision with rounding. */
1357 my_snprintf (result, sizeof (result), "%.2Lf %d", 999.996L, 33, 44, 55);
1358 ASSERT (strcmp (result, "1000.00 33") == 0);
1359 ASSERT (retval == strlen (result));
1362 /* Test the support of the %F format directive. */
1364 { /* A positive number. */
1367 my_snprintf (result, sizeof (result), "%F %d", 12.75, 33, 44, 55);
1368 ASSERT (strcmp (result, "12.750000 33") == 0);
1369 ASSERT (retval == strlen (result));
1372 { /* A larger positive number. */
1375 my_snprintf (result, sizeof (result), "%F %d", 1234567.0, 33, 44, 55);
1376 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1377 ASSERT (retval == strlen (result));
1380 { /* A negative number. */
1383 my_snprintf (result, sizeof (result), "%F %d", -0.03125, 33, 44, 55);
1384 ASSERT (strcmp (result, "-0.031250 33") == 0);
1385 ASSERT (retval == strlen (result));
1388 { /* Positive zero. */
1391 my_snprintf (result, sizeof (result), "%F %d", 0.0, 33, 44, 55);
1392 ASSERT (strcmp (result, "0.000000 33") == 0);
1393 ASSERT (retval == strlen (result));
1396 { /* Negative zero. */
1399 my_snprintf (result, sizeof (result), "%F %d", minus_zerod, 33, 44, 55);
1400 if (have_minus_zero ())
1401 ASSERT (strcmp (result, "-0.000000 33") == 0);
1402 ASSERT (retval == strlen (result));
1405 { /* Positive infinity. */
1408 my_snprintf (result, sizeof (result), "%F %d", 1.0 / 0.0, 33, 44, 55);
1409 ASSERT (strcmp (result, "INF 33") == 0
1410 || strcmp (result, "INFINITY 33") == 0);
1411 ASSERT (retval == strlen (result));
1414 { /* Negative infinity. */
1417 my_snprintf (result, sizeof (result), "%F %d", -1.0 / 0.0, 33, 44, 55);
1418 ASSERT (strcmp (result, "-INF 33") == 0
1419 || strcmp (result, "-INFINITY 33") == 0);
1420 ASSERT (retval == strlen (result));
1426 my_snprintf (result, sizeof (result), "%F %d", NaNd (), 33, 44, 55);
1427 ASSERT (strlen (result) >= 3 + 3
1428 && strisnan (result, 0, strlen (result) - 3, 1)
1429 && strcmp (result + strlen (result) - 3, " 33") == 0);
1430 ASSERT (retval == strlen (result));
1436 my_snprintf (result, sizeof (result), "%015F %d", 1234.0, 33, 44, 55);
1437 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1438 ASSERT (retval == strlen (result));
1441 { /* FLAG_ZERO with infinite number. */
1444 my_snprintf (result, sizeof (result), "%015F %d", -1.0 / 0.0, 33, 44, 55);
1445 ASSERT (strcmp (result, " -INF 33") == 0
1446 || strcmp (result, " -INFINITY 33") == 0);
1447 ASSERT (retval == strlen (result));
1453 my_snprintf (result, sizeof (result), "%.F %d", 1234.0, 33, 44, 55);
1454 ASSERT (strcmp (result, "1234 33") == 0);
1455 ASSERT (retval == strlen (result));
1458 { /* Precision with no rounding. */
1461 my_snprintf (result, sizeof (result), "%.2F %d", 999.951, 33, 44, 55);
1462 ASSERT (strcmp (result, "999.95 33") == 0);
1463 ASSERT (retval == strlen (result));
1466 { /* Precision with rounding. */
1469 my_snprintf (result, sizeof (result), "%.2F %d", 999.996, 33, 44, 55);
1470 ASSERT (strcmp (result, "1000.00 33") == 0);
1471 ASSERT (retval == strlen (result));
1474 { /* A positive number. */
1477 my_snprintf (result, sizeof (result), "%LF %d", 12.75L, 33, 44, 55);
1478 ASSERT (strcmp (result, "12.750000 33") == 0);
1479 ASSERT (retval == strlen (result));
1482 { /* A larger positive number. */
1485 my_snprintf (result, sizeof (result), "%LF %d", 1234567.0L, 33, 44, 55);
1486 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1487 ASSERT (retval == strlen (result));
1490 { /* A negative number. */
1493 my_snprintf (result, sizeof (result), "%LF %d", -0.03125L, 33, 44, 55);
1494 ASSERT (strcmp (result, "-0.031250 33") == 0);
1495 ASSERT (retval == strlen (result));
1498 { /* Positive zero. */
1501 my_snprintf (result, sizeof (result), "%LF %d", 0.0L, 33, 44, 55);
1502 ASSERT (strcmp (result, "0.000000 33") == 0);
1503 ASSERT (retval == strlen (result));
1506 { /* Negative zero. */
1509 my_snprintf (result, sizeof (result), "%LF %d", minus_zerol, 33, 44, 55);
1510 if (have_minus_zero ())
1511 ASSERT (strcmp (result, "-0.000000 33") == 0);
1512 ASSERT (retval == strlen (result));
1515 { /* Positive infinity. */
1518 my_snprintf (result, sizeof (result), "%LF %d", 1.0L / 0.0L, 33, 44, 55);
1519 ASSERT (strcmp (result, "INF 33") == 0
1520 || strcmp (result, "INFINITY 33") == 0);
1521 ASSERT (retval == strlen (result));
1524 { /* Negative infinity. */
1527 my_snprintf (result, sizeof (result), "%LF %d", -1.0L / 0.0L, 33, 44, 55);
1528 ASSERT (strcmp (result, "-INF 33") == 0
1529 || strcmp (result, "-INFINITY 33") == 0);
1530 ASSERT (retval == strlen (result));
1536 my_snprintf (result, sizeof (result), "%LF %d", NaNl (), 33, 44, 55);
1537 ASSERT (strlen (result) >= 3 + 3
1538 && strisnan (result, 0, strlen (result) - 3, 1)
1539 && strcmp (result + strlen (result) - 3, " 33") == 0);
1540 ASSERT (retval == strlen (result));
1546 my_snprintf (result, sizeof (result), "%015LF %d", 1234.0L, 33, 44, 55);
1547 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1548 ASSERT (retval == strlen (result));
1551 { /* FLAG_ZERO with infinite number. */
1554 my_snprintf (result, sizeof (result), "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
1555 ASSERT (strcmp (result, " -INF 33") == 0
1556 || strcmp (result, " -INFINITY 33") == 0);
1557 ASSERT (retval == strlen (result));
1563 my_snprintf (result, sizeof (result), "%.LF %d", 1234.0L, 33, 44, 55);
1564 ASSERT (strcmp (result, "1234 33") == 0);
1565 ASSERT (retval == strlen (result));
1568 { /* Precision with no rounding. */
1571 my_snprintf (result, sizeof (result), "%.2LF %d", 999.951L, 33, 44, 55);
1572 ASSERT (strcmp (result, "999.95 33") == 0);
1573 ASSERT (retval == strlen (result));
1576 { /* Precision with rounding. */
1579 my_snprintf (result, sizeof (result), "%.2LF %d", 999.996L, 33, 44, 55);
1580 ASSERT (strcmp (result, "1000.00 33") == 0);
1581 ASSERT (retval == strlen (result));
1584 /* Test the support of the %e format directive. */
1586 { /* A positive number. */
1589 my_snprintf (result, sizeof (result), "%e %d", 12.75, 33, 44, 55);
1590 ASSERT (strcmp (result, "1.275000e+01 33") == 0
1591 || strcmp (result, "1.275000e+001 33") == 0);
1592 ASSERT (retval == strlen (result));
1595 { /* A larger positive number. */
1598 my_snprintf (result, sizeof (result), "%e %d", 1234567.0, 33, 44, 55);
1599 ASSERT (strcmp (result, "1.234567e+06 33") == 0
1600 || strcmp (result, "1.234567e+006 33") == 0);
1601 ASSERT (retval == strlen (result));
1604 { /* Small and large positive numbers. */
1605 static struct { double value; const char *string; } data[] =
1607 { 1.234321234321234e-37, "1.234321e-37" },
1608 { 1.234321234321234e-36, "1.234321e-36" },
1609 { 1.234321234321234e-35, "1.234321e-35" },
1610 { 1.234321234321234e-34, "1.234321e-34" },
1611 { 1.234321234321234e-33, "1.234321e-33" },
1612 { 1.234321234321234e-32, "1.234321e-32" },
1613 { 1.234321234321234e-31, "1.234321e-31" },
1614 { 1.234321234321234e-30, "1.234321e-30" },
1615 { 1.234321234321234e-29, "1.234321e-29" },
1616 { 1.234321234321234e-28, "1.234321e-28" },
1617 { 1.234321234321234e-27, "1.234321e-27" },
1618 { 1.234321234321234e-26, "1.234321e-26" },
1619 { 1.234321234321234e-25, "1.234321e-25" },
1620 { 1.234321234321234e-24, "1.234321e-24" },
1621 { 1.234321234321234e-23, "1.234321e-23" },
1622 { 1.234321234321234e-22, "1.234321e-22" },
1623 { 1.234321234321234e-21, "1.234321e-21" },
1624 { 1.234321234321234e-20, "1.234321e-20" },
1625 { 1.234321234321234e-19, "1.234321e-19" },
1626 { 1.234321234321234e-18, "1.234321e-18" },
1627 { 1.234321234321234e-17, "1.234321e-17" },
1628 { 1.234321234321234e-16, "1.234321e-16" },
1629 { 1.234321234321234e-15, "1.234321e-15" },
1630 { 1.234321234321234e-14, "1.234321e-14" },
1631 { 1.234321234321234e-13, "1.234321e-13" },
1632 { 1.234321234321234e-12, "1.234321e-12" },
1633 { 1.234321234321234e-11, "1.234321e-11" },
1634 { 1.234321234321234e-10, "1.234321e-10" },
1635 { 1.234321234321234e-9, "1.234321e-09" },
1636 { 1.234321234321234e-8, "1.234321e-08" },
1637 { 1.234321234321234e-7, "1.234321e-07" },
1638 { 1.234321234321234e-6, "1.234321e-06" },
1639 { 1.234321234321234e-5, "1.234321e-05" },
1640 { 1.234321234321234e-4, "1.234321e-04" },
1641 { 1.234321234321234e-3, "1.234321e-03" },
1642 { 1.234321234321234e-2, "1.234321e-02" },
1643 { 1.234321234321234e-1, "1.234321e-01" },
1644 { 1.234321234321234, "1.234321e+00" },
1645 { 1.234321234321234e1, "1.234321e+01" },
1646 { 1.234321234321234e2, "1.234321e+02" },
1647 { 1.234321234321234e3, "1.234321e+03" },
1648 { 1.234321234321234e4, "1.234321e+04" },
1649 { 1.234321234321234e5, "1.234321e+05" },
1650 { 1.234321234321234e6, "1.234321e+06" },
1651 { 1.234321234321234e7, "1.234321e+07" },
1652 { 1.234321234321234e8, "1.234321e+08" },
1653 { 1.234321234321234e9, "1.234321e+09" },
1654 { 1.234321234321234e10, "1.234321e+10" },
1655 { 1.234321234321234e11, "1.234321e+11" },
1656 { 1.234321234321234e12, "1.234321e+12" },
1657 { 1.234321234321234e13, "1.234321e+13" },
1658 { 1.234321234321234e14, "1.234321e+14" },
1659 { 1.234321234321234e15, "1.234321e+15" },
1660 { 1.234321234321234e16, "1.234321e+16" },
1661 { 1.234321234321234e17, "1.234321e+17" },
1662 { 1.234321234321234e18, "1.234321e+18" },
1663 { 1.234321234321234e19, "1.234321e+19" },
1664 { 1.234321234321234e20, "1.234321e+20" },
1665 { 1.234321234321234e21, "1.234321e+21" },
1666 { 1.234321234321234e22, "1.234321e+22" },
1667 { 1.234321234321234e23, "1.234321e+23" },
1668 { 1.234321234321234e24, "1.234321e+24" },
1669 { 1.234321234321234e25, "1.234321e+25" },
1670 { 1.234321234321234e26, "1.234321e+26" },
1671 { 1.234321234321234e27, "1.234321e+27" },
1672 { 1.234321234321234e28, "1.234321e+28" },
1673 { 1.234321234321234e29, "1.234321e+29" },
1674 { 1.234321234321234e30, "1.234321e+30" },
1675 { 1.234321234321234e31, "1.234321e+31" },
1676 { 1.234321234321234e32, "1.234321e+32" },
1677 { 1.234321234321234e33, "1.234321e+33" },
1678 { 1.234321234321234e34, "1.234321e+34" },
1679 { 1.234321234321234e35, "1.234321e+35" },
1680 { 1.234321234321234e36, "1.234321e+36" }
1683 for (k = 0; k < SIZEOF (data); k++)
1687 my_snprintf (result, sizeof (result), "%e", data[k].value);
1688 const char *expected = data[k].string;
1689 ASSERT (strcmp (result, expected) == 0
1690 /* Some implementations produce exponents with 3 digits. */
1691 || (strlen (result) == strlen (expected) + 1
1692 && memcmp (result, expected, strlen (expected) - 2) == 0
1693 && result[strlen (expected) - 2] == '0'
1694 && strcmp (result + strlen (expected) - 1,
1695 expected + strlen (expected) - 2)
1697 ASSERT (retval == strlen (result));
1701 { /* A negative number. */
1704 my_snprintf (result, sizeof (result), "%e %d", -0.03125, 33, 44, 55);
1705 ASSERT (strcmp (result, "-3.125000e-02 33") == 0
1706 || strcmp (result, "-3.125000e-002 33") == 0);
1707 ASSERT (retval == strlen (result));
1710 { /* Positive zero. */
1713 my_snprintf (result, sizeof (result), "%e %d", 0.0, 33, 44, 55);
1714 ASSERT (strcmp (result, "0.000000e+00 33") == 0
1715 || strcmp (result, "0.000000e+000 33") == 0);
1716 ASSERT (retval == strlen (result));
1719 { /* Negative zero. */
1722 my_snprintf (result, sizeof (result), "%e %d", minus_zerod, 33, 44, 55);
1723 if (have_minus_zero ())
1724 ASSERT (strcmp (result, "-0.000000e+00 33") == 0
1725 || strcmp (result, "-0.000000e+000 33") == 0);
1726 ASSERT (retval == strlen (result));
1729 { /* Positive infinity. */
1732 my_snprintf (result, sizeof (result), "%e %d", 1.0 / 0.0, 33, 44, 55);
1733 ASSERT (strcmp (result, "inf 33") == 0
1734 || strcmp (result, "infinity 33") == 0);
1735 ASSERT (retval == strlen (result));
1738 { /* Negative infinity. */
1741 my_snprintf (result, sizeof (result), "%e %d", -1.0 / 0.0, 33, 44, 55);
1742 ASSERT (strcmp (result, "-inf 33") == 0
1743 || strcmp (result, "-infinity 33") == 0);
1744 ASSERT (retval == strlen (result));
1750 my_snprintf (result, sizeof (result), "%e %d", NaNd (), 33, 44, 55);
1751 ASSERT (strlen (result) >= 3 + 3
1752 && strisnan (result, 0, strlen (result) - 3, 0)
1753 && strcmp (result + strlen (result) - 3, " 33") == 0);
1754 ASSERT (retval == strlen (result));
1760 my_snprintf (result, sizeof (result), "%15e %d", 1.75, 33, 44, 55);
1761 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
1762 || strcmp (result, " 1.750000e+000 33") == 0);
1763 ASSERT (retval == strlen (result));
1769 my_snprintf (result, sizeof (result), "%-15e %d", 1.75, 33, 44, 55);
1770 ASSERT (strcmp (result, "1.750000e+00 33") == 0
1771 || strcmp (result, "1.750000e+000 33") == 0);
1772 ASSERT (retval == strlen (result));
1775 { /* FLAG_SHOWSIGN. */
1778 my_snprintf (result, sizeof (result), "%+e %d", 1.75, 33, 44, 55);
1779 ASSERT (strcmp (result, "+1.750000e+00 33") == 0
1780 || strcmp (result, "+1.750000e+000 33") == 0);
1781 ASSERT (retval == strlen (result));
1787 my_snprintf (result, sizeof (result), "% e %d", 1.75, 33, 44, 55);
1788 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
1789 || strcmp (result, " 1.750000e+000 33") == 0);
1790 ASSERT (retval == strlen (result));
1796 my_snprintf (result, sizeof (result), "%#e %d", 1.75, 33, 44, 55);
1797 ASSERT (strcmp (result, "1.750000e+00 33") == 0
1798 || strcmp (result, "1.750000e+000 33") == 0);
1799 ASSERT (retval == strlen (result));
1805 my_snprintf (result, sizeof (result), "%#.e %d", 1.75, 33, 44, 55);
1806 ASSERT (strcmp (result, "2.e+00 33") == 0
1807 || strcmp (result, "2.e+000 33") == 0);
1808 ASSERT (retval == strlen (result));
1814 my_snprintf (result, sizeof (result), "%#.e %d", 9.75, 33, 44, 55);
1815 ASSERT (strcmp (result, "1.e+01 33") == 0
1816 || strcmp (result, "1.e+001 33") == 0);
1817 ASSERT (retval == strlen (result));
1820 { /* FLAG_ZERO with finite number. */
1823 my_snprintf (result, sizeof (result), "%015e %d", 1234.0, 33, 44, 55);
1824 ASSERT (strcmp (result, "0001.234000e+03 33") == 0
1825 || strcmp (result, "001.234000e+003 33") == 0);
1826 ASSERT (retval == strlen (result));
1829 { /* FLAG_ZERO with infinite number. */
1832 my_snprintf (result, sizeof (result), "%015e %d", -1.0 / 0.0, 33, 44, 55);
1833 ASSERT (strcmp (result, " -inf 33") == 0
1834 || strcmp (result, " -infinity 33") == 0);
1835 ASSERT (retval == strlen (result));
1838 { /* FLAG_ZERO with NaN. */
1841 my_snprintf (result, sizeof (result), "%050e %d", NaNd (), 33, 44, 55);
1842 ASSERT (strlen (result) == 50 + 3
1843 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1844 && strcmp (result + strlen (result) - 3, " 33") == 0);
1845 ASSERT (retval == strlen (result));
1851 my_snprintf (result, sizeof (result), "%.e %d", 1234.0, 33, 44, 55);
1852 ASSERT (strcmp (result, "1e+03 33") == 0
1853 || strcmp (result, "1e+003 33") == 0);
1854 ASSERT (retval == strlen (result));
1857 { /* Precision with no rounding. */
1860 my_snprintf (result, sizeof (result), "%.4e %d", 999.951, 33, 44, 55);
1861 ASSERT (strcmp (result, "9.9995e+02 33") == 0
1862 || strcmp (result, "9.9995e+002 33") == 0);
1863 ASSERT (retval == strlen (result));
1866 { /* Precision with rounding. */
1869 my_snprintf (result, sizeof (result), "%.4e %d", 999.996, 33, 44, 55);
1870 ASSERT (strcmp (result, "1.0000e+03 33") == 0
1871 || strcmp (result, "1.0000e+003 33") == 0);
1872 ASSERT (retval == strlen (result));
1875 { /* A positive number. */
1878 my_snprintf (result, sizeof (result), "%Le %d", 12.75L, 33, 44, 55);
1879 ASSERT (strcmp (result, "1.275000e+01 33") == 0
1880 || strcmp (result, "1.275000e+001 33") == 0);
1881 ASSERT (retval == strlen (result));
1884 { /* A larger positive number. */
1887 my_snprintf (result, sizeof (result), "%Le %d", 1234567.0L, 33, 44, 55);
1888 ASSERT (strcmp (result, "1.234567e+06 33") == 0
1889 || strcmp (result, "1.234567e+006 33") == 0);
1890 ASSERT (retval == strlen (result));
1893 { /* Small and large positive numbers. */
1894 static struct { long double value; const char *string; } data[] =
1896 { 1.234321234321234e-37L, "1.234321e-37" },
1897 { 1.234321234321234e-36L, "1.234321e-36" },
1898 { 1.234321234321234e-35L, "1.234321e-35" },
1899 { 1.234321234321234e-34L, "1.234321e-34" },
1900 { 1.234321234321234e-33L, "1.234321e-33" },
1901 { 1.234321234321234e-32L, "1.234321e-32" },
1902 { 1.234321234321234e-31L, "1.234321e-31" },
1903 { 1.234321234321234e-30L, "1.234321e-30" },
1904 { 1.234321234321234e-29L, "1.234321e-29" },
1905 { 1.234321234321234e-28L, "1.234321e-28" },
1906 { 1.234321234321234e-27L, "1.234321e-27" },
1907 { 1.234321234321234e-26L, "1.234321e-26" },
1908 { 1.234321234321234e-25L, "1.234321e-25" },
1909 { 1.234321234321234e-24L, "1.234321e-24" },
1910 { 1.234321234321234e-23L, "1.234321e-23" },
1911 { 1.234321234321234e-22L, "1.234321e-22" },
1912 { 1.234321234321234e-21L, "1.234321e-21" },
1913 { 1.234321234321234e-20L, "1.234321e-20" },
1914 { 1.234321234321234e-19L, "1.234321e-19" },
1915 { 1.234321234321234e-18L, "1.234321e-18" },
1916 { 1.234321234321234e-17L, "1.234321e-17" },
1917 { 1.234321234321234e-16L, "1.234321e-16" },
1918 { 1.234321234321234e-15L, "1.234321e-15" },
1919 { 1.234321234321234e-14L, "1.234321e-14" },
1920 { 1.234321234321234e-13L, "1.234321e-13" },
1921 { 1.234321234321234e-12L, "1.234321e-12" },
1922 { 1.234321234321234e-11L, "1.234321e-11" },
1923 { 1.234321234321234e-10L, "1.234321e-10" },
1924 { 1.234321234321234e-9L, "1.234321e-09" },
1925 { 1.234321234321234e-8L, "1.234321e-08" },
1926 { 1.234321234321234e-7L, "1.234321e-07" },
1927 { 1.234321234321234e-6L, "1.234321e-06" },
1928 { 1.234321234321234e-5L, "1.234321e-05" },
1929 { 1.234321234321234e-4L, "1.234321e-04" },
1930 { 1.234321234321234e-3L, "1.234321e-03" },
1931 { 1.234321234321234e-2L, "1.234321e-02" },
1932 { 1.234321234321234e-1L, "1.234321e-01" },
1933 { 1.234321234321234L, "1.234321e+00" },
1934 { 1.234321234321234e1L, "1.234321e+01" },
1935 { 1.234321234321234e2L, "1.234321e+02" },
1936 { 1.234321234321234e3L, "1.234321e+03" },
1937 { 1.234321234321234e4L, "1.234321e+04" },
1938 { 1.234321234321234e5L, "1.234321e+05" },
1939 { 1.234321234321234e6L, "1.234321e+06" },
1940 { 1.234321234321234e7L, "1.234321e+07" },
1941 { 1.234321234321234e8L, "1.234321e+08" },
1942 { 1.234321234321234e9L, "1.234321e+09" },
1943 { 1.234321234321234e10L, "1.234321e+10" },
1944 { 1.234321234321234e11L, "1.234321e+11" },
1945 { 1.234321234321234e12L, "1.234321e+12" },
1946 { 1.234321234321234e13L, "1.234321e+13" },
1947 { 1.234321234321234e14L, "1.234321e+14" },
1948 { 1.234321234321234e15L, "1.234321e+15" },
1949 { 1.234321234321234e16L, "1.234321e+16" },
1950 { 1.234321234321234e17L, "1.234321e+17" },
1951 { 1.234321234321234e18L, "1.234321e+18" },
1952 { 1.234321234321234e19L, "1.234321e+19" },
1953 { 1.234321234321234e20L, "1.234321e+20" },
1954 { 1.234321234321234e21L, "1.234321e+21" },
1955 { 1.234321234321234e22L, "1.234321e+22" },
1956 { 1.234321234321234e23L, "1.234321e+23" },
1957 { 1.234321234321234e24L, "1.234321e+24" },
1958 { 1.234321234321234e25L, "1.234321e+25" },
1959 { 1.234321234321234e26L, "1.234321e+26" },
1960 { 1.234321234321234e27L, "1.234321e+27" },
1961 { 1.234321234321234e28L, "1.234321e+28" },
1962 { 1.234321234321234e29L, "1.234321e+29" },
1963 { 1.234321234321234e30L, "1.234321e+30" },
1964 { 1.234321234321234e31L, "1.234321e+31" },
1965 { 1.234321234321234e32L, "1.234321e+32" },
1966 { 1.234321234321234e33L, "1.234321e+33" },
1967 { 1.234321234321234e34L, "1.234321e+34" },
1968 { 1.234321234321234e35L, "1.234321e+35" },
1969 { 1.234321234321234e36L, "1.234321e+36" }
1972 for (k = 0; k < SIZEOF (data); k++)
1976 my_snprintf (result, sizeof (result), "%Le", data[k].value);
1977 const char *expected = data[k].string;
1978 ASSERT (strcmp (result, expected) == 0
1979 /* Some implementations produce exponents with 3 digits. */
1980 || (strlen (result) == strlen (expected) + 1
1981 && memcmp (result, expected, strlen (expected) - 2) == 0
1982 && result[strlen (expected) - 2] == '0'
1983 && strcmp (result + strlen (expected) - 1,
1984 expected + strlen (expected) - 2)
1986 ASSERT (retval == strlen (result));
1990 { /* A negative number. */
1993 my_snprintf (result, sizeof (result), "%Le %d", -0.03125L, 33, 44, 55);
1994 ASSERT (strcmp (result, "-3.125000e-02 33") == 0
1995 || strcmp (result, "-3.125000e-002 33") == 0);
1996 ASSERT (retval == strlen (result));
1999 { /* Positive zero. */
2002 my_snprintf (result, sizeof (result), "%Le %d", 0.0L, 33, 44, 55);
2003 ASSERT (strcmp (result, "0.000000e+00 33") == 0
2004 || strcmp (result, "0.000000e+000 33") == 0);
2005 ASSERT (retval == strlen (result));
2008 { /* Negative zero. */
2011 my_snprintf (result, sizeof (result), "%Le %d", minus_zerol, 33, 44, 55);
2012 if (have_minus_zero ())
2013 ASSERT (strcmp (result, "-0.000000e+00 33") == 0
2014 || strcmp (result, "-0.000000e+000 33") == 0);
2015 ASSERT (retval == strlen (result));
2018 { /* Positive infinity. */
2021 my_snprintf (result, sizeof (result), "%Le %d", 1.0L / 0.0L, 33, 44, 55);
2022 ASSERT (strcmp (result, "inf 33") == 0
2023 || strcmp (result, "infinity 33") == 0);
2024 ASSERT (retval == strlen (result));
2027 { /* Negative infinity. */
2030 my_snprintf (result, sizeof (result), "%Le %d", -1.0L / 0.0L, 33, 44, 55);
2031 ASSERT (strcmp (result, "-inf 33") == 0
2032 || strcmp (result, "-infinity 33") == 0);
2033 ASSERT (retval == strlen (result));
2039 my_snprintf (result, sizeof (result), "%Le %d", NaNl (), 33, 44, 55);
2040 ASSERT (strlen (result) >= 3 + 3
2041 && strisnan (result, 0, strlen (result) - 3, 0)
2042 && strcmp (result + strlen (result) - 3, " 33") == 0);
2043 ASSERT (retval == strlen (result));
2045 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
2047 static union { unsigned int word[4]; long double value; } x =
2048 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
2051 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2052 ASSERT (strlen (result) >= 3 + 3
2053 && strisnan (result, 0, strlen (result) - 3, 0)
2054 && strcmp (result + strlen (result) - 3, " 33") == 0);
2055 ASSERT (retval == strlen (result));
2058 /* Signalling NaN. */
2059 static union { unsigned int word[4]; long double value; } x =
2060 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
2063 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2064 ASSERT (strlen (result) >= 3 + 3
2065 && strisnan (result, 0, strlen (result) - 3, 0)
2066 && strcmp (result + strlen (result) - 3, " 33") == 0);
2067 ASSERT (retval == strlen (result));
2069 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
2070 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
2071 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
2072 Application Architecture.
2073 Table 5-2 "Floating-Point Register Encodings"
2074 Figure 5-6 "Memory to Floating-Point Register Data Translation"
2077 static union { unsigned int word[4]; long double value; } x =
2078 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
2081 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2082 ASSERT (strlen (result) >= 3 + 3
2083 && strisnan (result, 0, strlen (result) - 3, 0)
2084 && strcmp (result + strlen (result) - 3, " 33") == 0);
2085 ASSERT (retval == strlen (result));
2087 { /* Pseudo-Infinity. */
2088 static union { unsigned int word[4]; long double value; } x =
2089 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
2092 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2093 ASSERT (strlen (result) >= 3 + 3
2094 && strisnan (result, 0, strlen (result) - 3, 0)
2095 && strcmp (result + strlen (result) - 3, " 33") == 0);
2096 ASSERT (retval == strlen (result));
2098 { /* Pseudo-Zero. */
2099 static union { unsigned int word[4]; long double value; } x =
2100 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
2103 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2104 ASSERT (strlen (result) >= 3 + 3
2105 && strisnan (result, 0, strlen (result) - 3, 0)
2106 && strcmp (result + strlen (result) - 3, " 33") == 0);
2107 ASSERT (retval == strlen (result));
2109 { /* Unnormalized number. */
2110 static union { unsigned int word[4]; long double value; } x =
2111 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
2114 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2115 ASSERT (strlen (result) >= 3 + 3
2116 && strisnan (result, 0, strlen (result) - 3, 0)
2117 && strcmp (result + strlen (result) - 3, " 33") == 0);
2118 ASSERT (retval == strlen (result));
2120 { /* Pseudo-Denormal. */
2121 static union { unsigned int word[4]; long double value; } x =
2122 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
2125 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2126 ASSERT (strlen (result) >= 3 + 3
2127 && strisnan (result, 0, strlen (result) - 3, 0)
2128 && strcmp (result + strlen (result) - 3, " 33") == 0);
2129 ASSERT (retval == strlen (result));
2136 my_snprintf (result, sizeof (result), "%15Le %d", 1.75L, 33, 44, 55);
2137 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2138 || strcmp (result, " 1.750000e+000 33") == 0);
2139 ASSERT (retval == strlen (result));
2145 my_snprintf (result, sizeof (result), "%-15Le %d", 1.75L, 33, 44, 55);
2146 ASSERT (strcmp (result, "1.750000e+00 33") == 0
2147 || strcmp (result, "1.750000e+000 33") == 0);
2148 ASSERT (retval == strlen (result));
2151 { /* FLAG_SHOWSIGN. */
2154 my_snprintf (result, sizeof (result), "%+Le %d", 1.75L, 33, 44, 55);
2155 ASSERT (strcmp (result, "+1.750000e+00 33") == 0
2156 || strcmp (result, "+1.750000e+000 33") == 0);
2157 ASSERT (retval == strlen (result));
2163 my_snprintf (result, sizeof (result), "% Le %d", 1.75L, 33, 44, 55);
2164 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2165 || strcmp (result, " 1.750000e+000 33") == 0);
2166 ASSERT (retval == strlen (result));
2172 my_snprintf (result, sizeof (result), "%#Le %d", 1.75L, 33, 44, 55);
2173 ASSERT (strcmp (result, "1.750000e+00 33") == 0
2174 || strcmp (result, "1.750000e+000 33") == 0);
2175 ASSERT (retval == strlen (result));
2181 my_snprintf (result, sizeof (result), "%#.Le %d", 1.75L, 33, 44, 55);
2182 ASSERT (strcmp (result, "2.e+00 33") == 0
2183 || strcmp (result, "2.e+000 33") == 0);
2184 ASSERT (retval == strlen (result));
2190 my_snprintf (result, sizeof (result), "%#.Le %d", 9.75L, 33, 44, 55);
2191 ASSERT (strcmp (result, "1.e+01 33") == 0
2192 || strcmp (result, "1.e+001 33") == 0);
2193 ASSERT (retval == strlen (result));
2196 { /* FLAG_ZERO with finite number. */
2199 my_snprintf (result, sizeof (result), "%015Le %d", 1234.0L, 33, 44, 55);
2200 ASSERT (strcmp (result, "0001.234000e+03 33") == 0
2201 || strcmp (result, "001.234000e+003 33") == 0);
2202 ASSERT (retval == strlen (result));
2205 { /* FLAG_ZERO with infinite number. */
2208 my_snprintf (result, sizeof (result), "%015Le %d", -1.0L / 0.0L, 33, 44, 55);
2209 ASSERT (strcmp (result, " -inf 33") == 0
2210 || strcmp (result, " -infinity 33") == 0);
2211 ASSERT (retval == strlen (result));
2214 { /* FLAG_ZERO with NaN. */
2217 my_snprintf (result, sizeof (result), "%050Le %d", NaNl (), 33, 44, 55);
2218 ASSERT (strlen (result) == 50 + 3
2219 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2220 && strcmp (result + strlen (result) - 3, " 33") == 0);
2221 ASSERT (retval == strlen (result));
2227 my_snprintf (result, sizeof (result), "%.Le %d", 1234.0L, 33, 44, 55);
2228 ASSERT (strcmp (result, "1e+03 33") == 0
2229 || strcmp (result, "1e+003 33") == 0);
2230 ASSERT (retval == strlen (result));
2233 { /* Precision with no rounding. */
2236 my_snprintf (result, sizeof (result), "%.4Le %d", 999.951L, 33, 44, 55);
2237 ASSERT (strcmp (result, "9.9995e+02 33") == 0
2238 || strcmp (result, "9.9995e+002 33") == 0);
2239 ASSERT (retval == strlen (result));
2242 { /* Precision with rounding. */
2245 my_snprintf (result, sizeof (result), "%.4Le %d", 999.996L, 33, 44, 55);
2246 ASSERT (strcmp (result, "1.0000e+03 33") == 0
2247 || strcmp (result, "1.0000e+003 33") == 0);
2248 ASSERT (retval == strlen (result));
2251 /* Test the support of the %g format directive. */
2253 { /* A positive number. */
2256 my_snprintf (result, sizeof (result), "%g %d", 12.75, 33, 44, 55);
2257 ASSERT (strcmp (result, "12.75 33") == 0);
2258 ASSERT (retval == strlen (result));
2261 { /* A larger positive number. */
2264 my_snprintf (result, sizeof (result), "%g %d", 1234567.0, 33, 44, 55);
2265 ASSERT (strcmp (result, "1.23457e+06 33") == 0
2266 || strcmp (result, "1.23457e+006 33") == 0);
2267 ASSERT (retval == strlen (result));
2270 { /* Small and large positive numbers. */
2271 static struct { double value; const char *string; } data[] =
2273 { 1.234321234321234e-37, "1.23432e-37" },
2274 { 1.234321234321234e-36, "1.23432e-36" },
2275 { 1.234321234321234e-35, "1.23432e-35" },
2276 { 1.234321234321234e-34, "1.23432e-34" },
2277 { 1.234321234321234e-33, "1.23432e-33" },
2278 { 1.234321234321234e-32, "1.23432e-32" },
2279 { 1.234321234321234e-31, "1.23432e-31" },
2280 { 1.234321234321234e-30, "1.23432e-30" },
2281 { 1.234321234321234e-29, "1.23432e-29" },
2282 { 1.234321234321234e-28, "1.23432e-28" },
2283 { 1.234321234321234e-27, "1.23432e-27" },
2284 { 1.234321234321234e-26, "1.23432e-26" },
2285 { 1.234321234321234e-25, "1.23432e-25" },
2286 { 1.234321234321234e-24, "1.23432e-24" },
2287 { 1.234321234321234e-23, "1.23432e-23" },
2288 { 1.234321234321234e-22, "1.23432e-22" },
2289 { 1.234321234321234e-21, "1.23432e-21" },
2290 { 1.234321234321234e-20, "1.23432e-20" },
2291 { 1.234321234321234e-19, "1.23432e-19" },
2292 { 1.234321234321234e-18, "1.23432e-18" },
2293 { 1.234321234321234e-17, "1.23432e-17" },
2294 { 1.234321234321234e-16, "1.23432e-16" },
2295 { 1.234321234321234e-15, "1.23432e-15" },
2296 { 1.234321234321234e-14, "1.23432e-14" },
2297 { 1.234321234321234e-13, "1.23432e-13" },
2298 { 1.234321234321234e-12, "1.23432e-12" },
2299 { 1.234321234321234e-11, "1.23432e-11" },
2300 { 1.234321234321234e-10, "1.23432e-10" },
2301 { 1.234321234321234e-9, "1.23432e-09" },
2302 { 1.234321234321234e-8, "1.23432e-08" },
2303 { 1.234321234321234e-7, "1.23432e-07" },
2304 { 1.234321234321234e-6, "1.23432e-06" },
2305 { 1.234321234321234e-5, "1.23432e-05" },
2306 { 1.234321234321234e-4, "0.000123432" },
2307 { 1.234321234321234e-3, "0.00123432" },
2308 { 1.234321234321234e-2, "0.0123432" },
2309 { 1.234321234321234e-1, "0.123432" },
2310 { 1.234321234321234, "1.23432" },
2311 { 1.234321234321234e1, "12.3432" },
2312 { 1.234321234321234e2, "123.432" },
2313 { 1.234321234321234e3, "1234.32" },
2314 { 1.234321234321234e4, "12343.2" },
2315 { 1.234321234321234e5, "123432" },
2316 { 1.234321234321234e6, "1.23432e+06" },
2317 { 1.234321234321234e7, "1.23432e+07" },
2318 { 1.234321234321234e8, "1.23432e+08" },
2319 { 1.234321234321234e9, "1.23432e+09" },
2320 { 1.234321234321234e10, "1.23432e+10" },
2321 { 1.234321234321234e11, "1.23432e+11" },
2322 { 1.234321234321234e12, "1.23432e+12" },
2323 { 1.234321234321234e13, "1.23432e+13" },
2324 { 1.234321234321234e14, "1.23432e+14" },
2325 { 1.234321234321234e15, "1.23432e+15" },
2326 { 1.234321234321234e16, "1.23432e+16" },
2327 { 1.234321234321234e17, "1.23432e+17" },
2328 { 1.234321234321234e18, "1.23432e+18" },
2329 { 1.234321234321234e19, "1.23432e+19" },
2330 { 1.234321234321234e20, "1.23432e+20" },
2331 { 1.234321234321234e21, "1.23432e+21" },
2332 { 1.234321234321234e22, "1.23432e+22" },
2333 { 1.234321234321234e23, "1.23432e+23" },
2334 { 1.234321234321234e24, "1.23432e+24" },
2335 { 1.234321234321234e25, "1.23432e+25" },
2336 { 1.234321234321234e26, "1.23432e+26" },
2337 { 1.234321234321234e27, "1.23432e+27" },
2338 { 1.234321234321234e28, "1.23432e+28" },
2339 { 1.234321234321234e29, "1.23432e+29" },
2340 { 1.234321234321234e30, "1.23432e+30" },
2341 { 1.234321234321234e31, "1.23432e+31" },
2342 { 1.234321234321234e32, "1.23432e+32" },
2343 { 1.234321234321234e33, "1.23432e+33" },
2344 { 1.234321234321234e34, "1.23432e+34" },
2345 { 1.234321234321234e35, "1.23432e+35" },
2346 { 1.234321234321234e36, "1.23432e+36" }
2349 for (k = 0; k < SIZEOF (data); k++)
2353 my_snprintf (result, sizeof (result), "%g", data[k].value);
2354 const char *expected = data[k].string;
2355 ASSERT (strcmp (result, expected) == 0
2356 /* Some implementations produce exponents with 3 digits. */
2357 || (expected[strlen (expected) - 4] == 'e'
2358 && strlen (result) == strlen (expected) + 1
2359 && memcmp (result, expected, strlen (expected) - 2) == 0
2360 && result[strlen (expected) - 2] == '0'
2361 && strcmp (result + strlen (expected) - 1,
2362 expected + strlen (expected) - 2)
2364 ASSERT (retval == strlen (result));
2368 { /* A negative number. */
2371 my_snprintf (result, sizeof (result), "%g %d", -0.03125, 33, 44, 55);
2372 ASSERT (strcmp (result, "-0.03125 33") == 0);
2373 ASSERT (retval == strlen (result));
2376 { /* Positive zero. */
2379 my_snprintf (result, sizeof (result), "%g %d", 0.0, 33, 44, 55);
2380 ASSERT (strcmp (result, "0 33") == 0);
2381 ASSERT (retval == strlen (result));
2384 { /* Negative zero. */
2387 my_snprintf (result, sizeof (result), "%g %d", minus_zerod, 33, 44, 55);
2388 if (have_minus_zero ())
2389 ASSERT (strcmp (result, "-0 33") == 0);
2390 ASSERT (retval == strlen (result));
2393 { /* Positive infinity. */
2396 my_snprintf (result, sizeof (result), "%g %d", 1.0 / 0.0, 33, 44, 55);
2397 ASSERT (strcmp (result, "inf 33") == 0
2398 || strcmp (result, "infinity 33") == 0);
2399 ASSERT (retval == strlen (result));
2402 { /* Negative infinity. */
2405 my_snprintf (result, sizeof (result), "%g %d", -1.0 / 0.0, 33, 44, 55);
2406 ASSERT (strcmp (result, "-inf 33") == 0
2407 || strcmp (result, "-infinity 33") == 0);
2408 ASSERT (retval == strlen (result));
2414 my_snprintf (result, sizeof (result), "%g %d", NaNd (), 33, 44, 55);
2415 ASSERT (strlen (result) >= 3 + 3
2416 && strisnan (result, 0, strlen (result) - 3, 0)
2417 && strcmp (result + strlen (result) - 3, " 33") == 0);
2418 ASSERT (retval == strlen (result));
2424 my_snprintf (result, sizeof (result), "%10g %d", 1.75, 33, 44, 55);
2425 ASSERT (strcmp (result, " 1.75 33") == 0);
2426 ASSERT (retval == strlen (result));
2432 my_snprintf (result, sizeof (result), "%-10g %d", 1.75, 33, 44, 55);
2433 ASSERT (strcmp (result, "1.75 33") == 0);
2434 ASSERT (retval == strlen (result));
2437 { /* FLAG_SHOWSIGN. */
2440 my_snprintf (result, sizeof (result), "%+g %d", 1.75, 33, 44, 55);
2441 ASSERT (strcmp (result, "+1.75 33") == 0);
2442 ASSERT (retval == strlen (result));
2448 my_snprintf (result, sizeof (result), "% g %d", 1.75, 33, 44, 55);
2449 ASSERT (strcmp (result, " 1.75 33") == 0);
2450 ASSERT (retval == strlen (result));
2456 my_snprintf (result, sizeof (result), "%#g %d", 1.75, 33, 44, 55);
2457 ASSERT (strcmp (result, "1.75000 33") == 0);
2458 ASSERT (retval == strlen (result));
2464 my_snprintf (result, sizeof (result), "%#.g %d", 1.75, 33, 44, 55);
2465 ASSERT (strcmp (result, "2. 33") == 0);
2466 ASSERT (retval == strlen (result));
2472 my_snprintf (result, sizeof (result), "%#.g %d", 9.75, 33, 44, 55);
2473 ASSERT (strcmp (result, "1.e+01 33") == 0
2474 || strcmp (result, "1.e+001 33") == 0);
2475 ASSERT (retval == strlen (result));
2478 { /* FLAG_ZERO with finite number. */
2481 my_snprintf (result, sizeof (result), "%010g %d", 1234.0, 33, 44, 55);
2482 ASSERT (strcmp (result, "0000001234 33") == 0);
2483 ASSERT (retval == strlen (result));
2486 { /* FLAG_ZERO with infinite number. */
2489 my_snprintf (result, sizeof (result), "%015g %d", -1.0 / 0.0, 33, 44, 55);
2490 ASSERT (strcmp (result, " -inf 33") == 0
2491 || strcmp (result, " -infinity 33") == 0);
2492 ASSERT (retval == strlen (result));
2495 { /* FLAG_ZERO with NaN. */
2498 my_snprintf (result, sizeof (result), "%050g %d", NaNd (), 33, 44, 55);
2499 ASSERT (strlen (result) == 50 + 3
2500 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2501 && strcmp (result + strlen (result) - 3, " 33") == 0);
2502 ASSERT (retval == strlen (result));
2508 my_snprintf (result, sizeof (result), "%.g %d", 1234.0, 33, 44, 55);
2509 ASSERT (strcmp (result, "1e+03 33") == 0
2510 || strcmp (result, "1e+003 33") == 0);
2511 ASSERT (retval == strlen (result));
2514 { /* Precision with no rounding. */
2517 my_snprintf (result, sizeof (result), "%.5g %d", 999.951, 33, 44, 55);
2518 ASSERT (strcmp (result, "999.95 33") == 0);
2519 ASSERT (retval == strlen (result));
2522 { /* Precision with rounding. */
2525 my_snprintf (result, sizeof (result), "%.5g %d", 999.996, 33, 44, 55);
2526 ASSERT (strcmp (result, "1000 33") == 0);
2527 ASSERT (retval == strlen (result));
2530 { /* A positive number. */
2533 my_snprintf (result, sizeof (result), "%Lg %d", 12.75L, 33, 44, 55);
2534 ASSERT (strcmp (result, "12.75 33") == 0);
2535 ASSERT (retval == strlen (result));
2538 { /* A larger positive number. */
2541 my_snprintf (result, sizeof (result), "%Lg %d", 1234567.0L, 33, 44, 55);
2542 ASSERT (strcmp (result, "1.23457e+06 33") == 0
2543 || strcmp (result, "1.23457e+006 33") == 0);
2544 ASSERT (retval == strlen (result));
2547 { /* Small and large positive numbers. */
2548 static struct { long double value; const char *string; } data[] =
2550 { 1.234321234321234e-37L, "1.23432e-37" },
2551 { 1.234321234321234e-36L, "1.23432e-36" },
2552 { 1.234321234321234e-35L, "1.23432e-35" },
2553 { 1.234321234321234e-34L, "1.23432e-34" },
2554 { 1.234321234321234e-33L, "1.23432e-33" },
2555 { 1.234321234321234e-32L, "1.23432e-32" },
2556 { 1.234321234321234e-31L, "1.23432e-31" },
2557 { 1.234321234321234e-30L, "1.23432e-30" },
2558 { 1.234321234321234e-29L, "1.23432e-29" },
2559 { 1.234321234321234e-28L, "1.23432e-28" },
2560 { 1.234321234321234e-27L, "1.23432e-27" },
2561 { 1.234321234321234e-26L, "1.23432e-26" },
2562 { 1.234321234321234e-25L, "1.23432e-25" },
2563 { 1.234321234321234e-24L, "1.23432e-24" },
2564 { 1.234321234321234e-23L, "1.23432e-23" },
2565 { 1.234321234321234e-22L, "1.23432e-22" },
2566 { 1.234321234321234e-21L, "1.23432e-21" },
2567 { 1.234321234321234e-20L, "1.23432e-20" },
2568 { 1.234321234321234e-19L, "1.23432e-19" },
2569 { 1.234321234321234e-18L, "1.23432e-18" },
2570 { 1.234321234321234e-17L, "1.23432e-17" },
2571 { 1.234321234321234e-16L, "1.23432e-16" },
2572 { 1.234321234321234e-15L, "1.23432e-15" },
2573 { 1.234321234321234e-14L, "1.23432e-14" },
2574 { 1.234321234321234e-13L, "1.23432e-13" },
2575 { 1.234321234321234e-12L, "1.23432e-12" },
2576 { 1.234321234321234e-11L, "1.23432e-11" },
2577 { 1.234321234321234e-10L, "1.23432e-10" },
2578 { 1.234321234321234e-9L, "1.23432e-09" },
2579 { 1.234321234321234e-8L, "1.23432e-08" },
2580 { 1.234321234321234e-7L, "1.23432e-07" },
2581 { 1.234321234321234e-6L, "1.23432e-06" },
2582 { 1.234321234321234e-5L, "1.23432e-05" },
2583 { 1.234321234321234e-4L, "0.000123432" },
2584 { 1.234321234321234e-3L, "0.00123432" },
2585 { 1.234321234321234e-2L, "0.0123432" },
2586 { 1.234321234321234e-1L, "0.123432" },
2587 { 1.234321234321234L, "1.23432" },
2588 { 1.234321234321234e1L, "12.3432" },
2589 { 1.234321234321234e2L, "123.432" },
2590 { 1.234321234321234e3L, "1234.32" },
2591 { 1.234321234321234e4L, "12343.2" },
2592 { 1.234321234321234e5L, "123432" },
2593 { 1.234321234321234e6L, "1.23432e+06" },
2594 { 1.234321234321234e7L, "1.23432e+07" },
2595 { 1.234321234321234e8L, "1.23432e+08" },
2596 { 1.234321234321234e9L, "1.23432e+09" },
2597 { 1.234321234321234e10L, "1.23432e+10" },
2598 { 1.234321234321234e11L, "1.23432e+11" },
2599 { 1.234321234321234e12L, "1.23432e+12" },
2600 { 1.234321234321234e13L, "1.23432e+13" },
2601 { 1.234321234321234e14L, "1.23432e+14" },
2602 { 1.234321234321234e15L, "1.23432e+15" },
2603 { 1.234321234321234e16L, "1.23432e+16" },
2604 { 1.234321234321234e17L, "1.23432e+17" },
2605 { 1.234321234321234e18L, "1.23432e+18" },
2606 { 1.234321234321234e19L, "1.23432e+19" },
2607 { 1.234321234321234e20L, "1.23432e+20" },
2608 { 1.234321234321234e21L, "1.23432e+21" },
2609 { 1.234321234321234e22L, "1.23432e+22" },
2610 { 1.234321234321234e23L, "1.23432e+23" },
2611 { 1.234321234321234e24L, "1.23432e+24" },
2612 { 1.234321234321234e25L, "1.23432e+25" },
2613 { 1.234321234321234e26L, "1.23432e+26" },
2614 { 1.234321234321234e27L, "1.23432e+27" },
2615 { 1.234321234321234e28L, "1.23432e+28" },
2616 { 1.234321234321234e29L, "1.23432e+29" },
2617 { 1.234321234321234e30L, "1.23432e+30" },
2618 { 1.234321234321234e31L, "1.23432e+31" },
2619 { 1.234321234321234e32L, "1.23432e+32" },
2620 { 1.234321234321234e33L, "1.23432e+33" },
2621 { 1.234321234321234e34L, "1.23432e+34" },
2622 { 1.234321234321234e35L, "1.23432e+35" },
2623 { 1.234321234321234e36L, "1.23432e+36" }
2626 for (k = 0; k < SIZEOF (data); k++)
2630 my_snprintf (result, sizeof (result), "%Lg", data[k].value);
2631 const char *expected = data[k].string;
2632 ASSERT (strcmp (result, expected) == 0
2633 /* Some implementations produce exponents with 3 digits. */
2634 || (expected[strlen (expected) - 4] == 'e'
2635 && strlen (result) == strlen (expected) + 1
2636 && memcmp (result, expected, strlen (expected) - 2) == 0
2637 && result[strlen (expected) - 2] == '0'
2638 && strcmp (result + strlen (expected) - 1,
2639 expected + strlen (expected) - 2)
2641 ASSERT (retval == strlen (result));
2645 { /* A negative number. */
2648 my_snprintf (result, sizeof (result), "%Lg %d", -0.03125L, 33, 44, 55);
2649 ASSERT (strcmp (result, "-0.03125 33") == 0);
2650 ASSERT (retval == strlen (result));
2653 { /* Positive zero. */
2656 my_snprintf (result, sizeof (result), "%Lg %d", 0.0L, 33, 44, 55);
2657 ASSERT (strcmp (result, "0 33") == 0);
2658 ASSERT (retval == strlen (result));
2661 { /* Negative zero. */
2664 my_snprintf (result, sizeof (result), "%Lg %d", minus_zerol, 33, 44, 55);
2665 if (have_minus_zero ())
2666 ASSERT (strcmp (result, "-0 33") == 0);
2667 ASSERT (retval == strlen (result));
2670 { /* Positive infinity. */
2673 my_snprintf (result, sizeof (result), "%Lg %d", 1.0L / 0.0L, 33, 44, 55);
2674 ASSERT (strcmp (result, "inf 33") == 0
2675 || strcmp (result, "infinity 33") == 0);
2676 ASSERT (retval == strlen (result));
2679 { /* Negative infinity. */
2682 my_snprintf (result, sizeof (result), "%Lg %d", -1.0L / 0.0L, 33, 44, 55);
2683 ASSERT (strcmp (result, "-inf 33") == 0
2684 || strcmp (result, "-infinity 33") == 0);
2685 ASSERT (retval == strlen (result));
2691 my_snprintf (result, sizeof (result), "%Lg %d", NaNl (), 33, 44, 55);
2692 ASSERT (strlen (result) >= 3 + 3
2693 && strisnan (result, 0, strlen (result) - 3, 0)
2694 && strcmp (result + strlen (result) - 3, " 33") == 0);
2695 ASSERT (retval == strlen (result));
2697 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
2699 static union { unsigned int word[4]; long double value; } x =
2700 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
2703 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2704 ASSERT (strlen (result) >= 3 + 3
2705 && strisnan (result, 0, strlen (result) - 3, 0)
2706 && strcmp (result + strlen (result) - 3, " 33") == 0);
2707 ASSERT (retval == strlen (result));
2710 /* Signalling NaN. */
2711 static union { unsigned int word[4]; long double value; } x =
2712 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
2715 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2716 ASSERT (strlen (result) >= 3 + 3
2717 && strisnan (result, 0, strlen (result) - 3, 0)
2718 && strcmp (result + strlen (result) - 3, " 33") == 0);
2719 ASSERT (retval == strlen (result));
2721 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
2722 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
2723 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
2724 Application Architecture.
2725 Table 5-2 "Floating-Point Register Encodings"
2726 Figure 5-6 "Memory to Floating-Point Register Data Translation"
2729 static union { unsigned int word[4]; long double value; } x =
2730 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
2733 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2734 ASSERT (strlen (result) >= 3 + 3
2735 && strisnan (result, 0, strlen (result) - 3, 0)
2736 && strcmp (result + strlen (result) - 3, " 33") == 0);
2737 ASSERT (retval == strlen (result));
2739 { /* Pseudo-Infinity. */
2740 static union { unsigned int word[4]; long double value; } x =
2741 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
2744 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2745 ASSERT (strlen (result) >= 3 + 3
2746 && strisnan (result, 0, strlen (result) - 3, 0)
2747 && strcmp (result + strlen (result) - 3, " 33") == 0);
2748 ASSERT (retval == strlen (result));
2750 { /* Pseudo-Zero. */
2751 static union { unsigned int word[4]; long double value; } x =
2752 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
2755 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2756 ASSERT (strlen (result) >= 3 + 3
2757 && strisnan (result, 0, strlen (result) - 3, 0)
2758 && strcmp (result + strlen (result) - 3, " 33") == 0);
2759 ASSERT (retval == strlen (result));
2761 { /* Unnormalized number. */
2762 static union { unsigned int word[4]; long double value; } x =
2763 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
2766 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2767 ASSERT (strlen (result) >= 3 + 3
2768 && strisnan (result, 0, strlen (result) - 3, 0)
2769 && strcmp (result + strlen (result) - 3, " 33") == 0);
2770 ASSERT (retval == strlen (result));
2772 { /* Pseudo-Denormal. */
2773 static union { unsigned int word[4]; long double value; } x =
2774 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
2777 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2778 ASSERT (strlen (result) >= 3 + 3
2779 && strisnan (result, 0, strlen (result) - 3, 0)
2780 && strcmp (result + strlen (result) - 3, " 33") == 0);
2781 ASSERT (retval == strlen (result));
2788 my_snprintf (result, sizeof (result), "%10Lg %d", 1.75L, 33, 44, 55);
2789 ASSERT (strcmp (result, " 1.75 33") == 0);
2790 ASSERT (retval == strlen (result));
2796 my_snprintf (result, sizeof (result), "%-10Lg %d", 1.75L, 33, 44, 55);
2797 ASSERT (strcmp (result, "1.75 33") == 0);
2798 ASSERT (retval == strlen (result));
2801 { /* FLAG_SHOWSIGN. */
2804 my_snprintf (result, sizeof (result), "%+Lg %d", 1.75L, 33, 44, 55);
2805 ASSERT (strcmp (result, "+1.75 33") == 0);
2806 ASSERT (retval == strlen (result));
2812 my_snprintf (result, sizeof (result), "% Lg %d", 1.75L, 33, 44, 55);
2813 ASSERT (strcmp (result, " 1.75 33") == 0);
2814 ASSERT (retval == strlen (result));
2820 my_snprintf (result, sizeof (result), "%#Lg %d", 1.75L, 33, 44, 55);
2821 ASSERT (strcmp (result, "1.75000 33") == 0);
2822 ASSERT (retval == strlen (result));
2828 my_snprintf (result, sizeof (result), "%#.Lg %d", 1.75L, 33, 44, 55);
2829 ASSERT (strcmp (result, "2. 33") == 0);
2830 ASSERT (retval == strlen (result));
2836 my_snprintf (result, sizeof (result), "%#.Lg %d", 9.75L, 33, 44, 55);
2837 ASSERT (strcmp (result, "1.e+01 33") == 0
2838 || strcmp (result, "1.e+001 33") == 0);
2839 ASSERT (retval == strlen (result));
2842 { /* FLAG_ZERO with finite number. */
2845 my_snprintf (result, sizeof (result), "%010Lg %d", 1234.0L, 33, 44, 55);
2846 ASSERT (strcmp (result, "0000001234 33") == 0);
2847 ASSERT (retval == strlen (result));
2850 { /* FLAG_ZERO with infinite number. */
2853 my_snprintf (result, sizeof (result), "%015Lg %d", -1.0L / 0.0L, 33, 44, 55);
2854 ASSERT (strcmp (result, " -inf 33") == 0
2855 || strcmp (result, " -infinity 33") == 0);
2856 ASSERT (retval == strlen (result));
2859 { /* FLAG_ZERO with NaN. */
2862 my_snprintf (result, sizeof (result), "%050Lg %d", NaNl (), 33, 44, 55);
2863 ASSERT (strlen (result) == 50 + 3
2864 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2865 && strcmp (result + strlen (result) - 3, " 33") == 0);
2866 ASSERT (retval == strlen (result));
2872 my_snprintf (result, sizeof (result), "%.Lg %d", 1234.0L, 33, 44, 55);
2873 ASSERT (strcmp (result, "1e+03 33") == 0
2874 || strcmp (result, "1e+003 33") == 0);
2875 ASSERT (retval == strlen (result));
2878 { /* Precision with no rounding. */
2881 my_snprintf (result, sizeof (result), "%.5Lg %d", 999.951L, 33, 44, 55);
2882 ASSERT (strcmp (result, "999.95 33") == 0);
2883 ASSERT (retval == strlen (result));
2886 { /* Precision with rounding. */
2889 my_snprintf (result, sizeof (result), "%.5Lg %d", 999.996L, 33, 44, 55);
2890 ASSERT (strcmp (result, "1000 33") == 0);
2891 ASSERT (retval == strlen (result));
2894 /* Test the support of the %n format directive. */
2900 my_snprintf (result, sizeof (result), "%d %n", 123, &count, 33, 44, 55);
2901 ASSERT (strcmp (result, "123 ") == 0);
2902 ASSERT (retval == strlen (result));
2903 ASSERT (count == 4);
2906 /* Test the support of the POSIX/XSI format strings with positions. */
2911 my_snprintf (result, sizeof (result), "%2$d %1$d", 33, 55);
2912 ASSERT (strcmp (result, "55 33") == 0);
2913 ASSERT (retval == strlen (result));
2916 /* Test the support of the grouping flag. */
2921 my_snprintf (result, sizeof (result), "%'d %d", 1234567, 99);
2922 ASSERT (result[strlen (result) - 1] == '9');
2923 ASSERT (retval == strlen (result));
2926 /* Test the support of the left-adjust flag. */
2931 my_snprintf (result, sizeof (result), "a%*sc", -3, "b");
2932 ASSERT (strcmp (result, "ab c") == 0);
2933 ASSERT (retval == strlen (result));
2939 my_snprintf (result, sizeof (result), "a%-*sc", 3, "b");
2940 ASSERT (strcmp (result, "ab c") == 0);
2941 ASSERT (retval == strlen (result));
2947 my_snprintf (result, sizeof (result), "a%-*sc", -3, "b");
2948 ASSERT (strcmp (result, "ab c") == 0);
2949 ASSERT (retval == strlen (result));
2952 /* Test the support of large precision. */
2957 my_snprintf (result, sizeof (result), "%.4000d %d", 1234567, 99);
2959 for (i = 0; i < 4000 - 7; i++)
2960 ASSERT (result[i] == '0');
2961 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
2962 ASSERT (retval == strlen (result));
2968 my_snprintf (result, sizeof (result), "%.*d %d", 4000, 1234567, 99);
2970 for (i = 0; i < 4000 - 7; i++)
2971 ASSERT (result[i] == '0');
2972 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
2973 ASSERT (retval == strlen (result));
2979 my_snprintf (result, sizeof (result), "%.4000d %d", -1234567, 99);
2981 ASSERT (result[0] == '-');
2982 for (i = 0; i < 4000 - 7; i++)
2983 ASSERT (result[1 + i] == '0');
2984 ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
2985 ASSERT (retval == strlen (result));
2991 my_snprintf (result, sizeof (result), "%.4000u %d", 1234567, 99);
2993 for (i = 0; i < 4000 - 7; i++)
2994 ASSERT (result[i] == '0');
2995 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
2996 ASSERT (retval == strlen (result));
3002 my_snprintf (result, sizeof (result), "%.4000o %d", 1234567, 99);
3004 for (i = 0; i < 4000 - 7; i++)
3005 ASSERT (result[i] == '0');
3006 ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
3007 ASSERT (retval == strlen (result));
3013 my_snprintf (result, sizeof (result), "%.4000x %d", 1234567, 99);
3015 for (i = 0; i < 4000 - 6; i++)
3016 ASSERT (result[i] == '0');
3017 ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
3018 ASSERT (retval == strlen (result));
3024 my_snprintf (result, sizeof (result), "%#.4000x %d", 1234567, 99);
3026 ASSERT (result[0] == '0');
3027 ASSERT (result[1] == 'x');
3028 for (i = 0; i < 4000 - 6; i++)
3029 ASSERT (result[2 + i] == '0');
3030 ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
3031 ASSERT (retval == strlen (result));
3037 my_snprintf (result, sizeof (result), "%.4000f %d", 1.0, 99);
3039 ASSERT (result[0] == '1');
3040 ASSERT (result[1] == '.');
3041 for (i = 0; i < 4000; i++)
3042 ASSERT (result[2 + i] == '0');
3043 ASSERT (strcmp (result + 2 + 4000, " 99") == 0);
3044 ASSERT (retval == strlen (result));
3053 for (i = 0; i < sizeof (input) - 1; i++)
3054 input[i] = 'a' + ((1000000 / (i + 1)) % 26);
3056 retval = my_snprintf (result, sizeof (result), "%.4000s %d", input, 99);
3057 ASSERT (memcmp (result, input, 4000) == 0);
3058 ASSERT (strcmp (result + 4000, " 99") == 0);
3059 ASSERT (retval == strlen (result));
3062 /* Test the support of the %s format directive. */
3064 /* To verify that these tests succeed, it is necessary to run them under
3065 a tool that checks against invalid memory accesses, such as ElectricFence
3066 or "valgrind --tool=memcheck". */
3070 for (i = 1; i <= 8; i++)
3076 block = (char *) malloc (i);
3077 memcpy (block, "abcdefgh", i);
3078 retval = my_snprintf (result, sizeof (result), "%.*s", (int) i, block);
3079 ASSERT (memcmp (result, block, i) == 0);
3080 ASSERT (result[i] == '\0');
3081 ASSERT (retval == strlen (result));
3089 for (i = 1; i <= 8; i++)
3096 block = (wchar_t *) malloc (i * sizeof (wchar_t));
3097 for (j = 0; j < i; j++)
3098 block[j] = "abcdefgh"[j];
3099 retval = my_snprintf (result, sizeof (result), "%.*ls", (int) i, block);
3100 ASSERT (memcmp (result, "abcdefgh", i) == 0);
3101 ASSERT (result[i] == '\0');
3102 ASSERT (retval == strlen (result));