1 /* Test of POSIX compatible vsnprintf() and snprintf() functions.
2 Copyright (C) 2007-2009 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. */
21 /* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0. */
25 static double plus_zero = 0.0;
26 double minus_zero = - plus_zero;
27 return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
30 /* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
31 So we use -zerod instead. */
34 /* On HP-UX 10.20, negating 0.0L does not yield -0.0L.
35 So we use minus_zerol instead.
36 IRIX cc can't put -0.0L into .data, but can compute at runtime.
37 Note that the expression -LDBL_MIN * LDBL_MIN does not work on other
38 platforms, such as when cross-compiling to PowerPC on MacOS X 10.5. */
39 #if defined __hpux || defined __sgi
41 compute_minus_zerol (void)
43 return -LDBL_MIN * LDBL_MIN;
45 # define minus_zerol compute_minus_zerol ()
47 long double minus_zerol = -0.0L;
50 /* Representation of an 80-bit 'long double' as an initializer for a sequence
51 of 'unsigned int' words. */
52 #ifdef WORDS_BIGENDIAN
53 # define LDBL80_WORDS(exponent,manthi,mantlo) \
54 { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
55 ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
56 (unsigned int) (mantlo) << 16 \
59 # define LDBL80_WORDS(exponent,manthi,mantlo) \
60 { mantlo, manthi, exponent }
64 strmatch (const char *pattern, const char *string)
66 if (strlen (pattern) != strlen (string))
68 for (; *pattern != '\0'; pattern++, string++)
69 if (*pattern != '*' && *string != *pattern)
74 /* Test whether string[start_index..end_index-1] is a valid textual
75 representation of NaN. */
77 strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
79 if (start_index < end_index)
81 if (string[start_index] == '-')
83 if (start_index + 3 <= end_index
84 && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
87 if (start_index == end_index
88 || (string[start_index] == '(' && string[end_index - 1] == ')'))
96 test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
101 /* Test return value convention. */
103 for (size = 0; size <= 8; size++)
107 memcpy (buf, "DEADBEEF", 8);
108 retval = my_snprintf (buf, size, "%d", 12345);
109 ASSERT (retval == 5);
114 ASSERT (memcmp (buf, "12345", size - 1) == 0);
115 ASSERT (buf[size - 1] == '\0');
117 ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
121 ASSERT (memcmp (buf, "12345\0EF", 8) == 0);
125 /* Test support of size specifiers as in C99. */
130 my_snprintf (result, sizeof (result), "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
131 ASSERT (strcmp (result, "12345671 33") == 0);
132 ASSERT (retval == strlen (result));
138 my_snprintf (result, sizeof (result), "%zu %d", (size_t) 12345672, 33, 44, 55);
139 ASSERT (strcmp (result, "12345672 33") == 0);
140 ASSERT (retval == strlen (result));
146 my_snprintf (result, sizeof (result), "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
147 ASSERT (strcmp (result, "12345673 33") == 0);
148 ASSERT (retval == strlen (result));
154 my_snprintf (result, sizeof (result), "%Lg %d", (long double) 1.5, 33, 44, 55);
155 ASSERT (strcmp (result, "1.5 33") == 0);
156 ASSERT (retval == strlen (result));
159 /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
160 output of floating-point numbers. */
162 { /* A positive number. */
165 my_snprintf (result, sizeof (result), "%a %d", 3.1416015625, 33, 44, 55);
166 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
167 || strcmp (result, "0x3.244p+0 33") == 0
168 || strcmp (result, "0x6.488p-1 33") == 0
169 || strcmp (result, "0xc.91p-2 33") == 0);
170 ASSERT (retval == strlen (result));
173 { /* A negative number. */
176 my_snprintf (result, sizeof (result), "%A %d", -3.1416015625, 33, 44, 55);
177 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
178 || strcmp (result, "-0X3.244P+0 33") == 0
179 || strcmp (result, "-0X6.488P-1 33") == 0
180 || strcmp (result, "-0XC.91P-2 33") == 0);
181 ASSERT (retval == strlen (result));
184 { /* Positive zero. */
187 my_snprintf (result, sizeof (result), "%a %d", 0.0, 33, 44, 55);
188 ASSERT (strcmp (result, "0x0p+0 33") == 0);
189 ASSERT (retval == strlen (result));
192 { /* Negative zero. */
195 my_snprintf (result, sizeof (result), "%a %d", -zerod, 33, 44, 55);
196 if (have_minus_zero ())
197 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
198 ASSERT (retval == strlen (result));
201 { /* Positive infinity. */
204 my_snprintf (result, sizeof (result), "%a %d", 1.0 / 0.0, 33, 44, 55);
205 ASSERT (strcmp (result, "inf 33") == 0);
206 ASSERT (retval == strlen (result));
209 { /* Negative infinity. */
212 my_snprintf (result, sizeof (result), "%a %d", -1.0 / 0.0, 33, 44, 55);
213 ASSERT (strcmp (result, "-inf 33") == 0);
214 ASSERT (retval == strlen (result));
220 my_snprintf (result, sizeof (result), "%a %d", NaNd (), 33, 44, 55);
221 ASSERT (strlen (result) >= 3 + 3
222 && strisnan (result, 0, strlen (result) - 3, 0)
223 && strcmp (result + strlen (result) - 3, " 33") == 0);
224 ASSERT (retval == strlen (result));
227 { /* Rounding near the decimal point. */
230 my_snprintf (result, sizeof (result), "%.0a %d", 1.5, 33, 44, 55);
231 ASSERT (strcmp (result, "0x2p+0 33") == 0
232 || strcmp (result, "0x3p-1 33") == 0
233 || strcmp (result, "0x6p-2 33") == 0
234 || strcmp (result, "0xcp-3 33") == 0);
235 ASSERT (retval == strlen (result));
238 { /* Rounding with precision 0. */
241 my_snprintf (result, sizeof (result), "%.0a %d", 1.51, 33, 44, 55);
242 ASSERT (strcmp (result, "0x2p+0 33") == 0
243 || strcmp (result, "0x3p-1 33") == 0
244 || strcmp (result, "0x6p-2 33") == 0
245 || strcmp (result, "0xcp-3 33") == 0);
246 ASSERT (retval == strlen (result));
249 { /* Rounding with precision 1. */
252 my_snprintf (result, sizeof (result), "%.1a %d", 1.51, 33, 44, 55);
253 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
254 || strcmp (result, "0x3.0p-1 33") == 0
255 || strcmp (result, "0x6.1p-2 33") == 0
256 || strcmp (result, "0xc.1p-3 33") == 0);
257 ASSERT (retval == strlen (result));
260 { /* Rounding with precision 2. */
263 my_snprintf (result, sizeof (result), "%.2a %d", 1.51, 33, 44, 55);
264 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
265 || strcmp (result, "0x3.05p-1 33") == 0
266 || strcmp (result, "0x6.0ap-2 33") == 0
267 || strcmp (result, "0xc.14p-3 33") == 0);
268 ASSERT (retval == strlen (result));
271 { /* Rounding with precision 3. */
274 my_snprintf (result, sizeof (result), "%.3a %d", 1.51, 33, 44, 55);
275 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
276 || strcmp (result, "0x3.052p-1 33") == 0
277 || strcmp (result, "0x6.0a4p-2 33") == 0
278 || strcmp (result, "0xc.148p-3 33") == 0);
279 ASSERT (retval == strlen (result));
282 { /* Rounding can turn a ...FFF into a ...000. */
285 my_snprintf (result, sizeof (result), "%.3a %d", 1.49999, 33, 44, 55);
286 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
287 || strcmp (result, "0x3.000p-1 33") == 0
288 || strcmp (result, "0x6.000p-2 33") == 0
289 || strcmp (result, "0xc.000p-3 33") == 0);
290 ASSERT (retval == strlen (result));
293 { /* Rounding can turn a ...FFF into a ...000.
294 This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
297 my_snprintf (result, sizeof (result), "%.1a %d", 1.999, 33, 44, 55);
298 ASSERT (strcmp (result, "0x1.0p+1 33") == 0
299 || strcmp (result, "0x2.0p+0 33") == 0
300 || strcmp (result, "0x4.0p-1 33") == 0
301 || strcmp (result, "0x8.0p-2 33") == 0);
302 ASSERT (retval == strlen (result));
308 my_snprintf (result, sizeof (result), "%10a %d", 1.75, 33, 44, 55);
309 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
310 || strcmp (result, " 0x3.8p-1 33") == 0
311 || strcmp (result, " 0x7p-2 33") == 0
312 || strcmp (result, " 0xep-3 33") == 0);
313 ASSERT (retval == strlen (result));
316 { /* Small precision. */
319 my_snprintf (result, sizeof (result), "%.10a %d", 1.75, 33, 44, 55);
320 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
321 || strcmp (result, "0x3.8000000000p-1 33") == 0
322 || strcmp (result, "0x7.0000000000p-2 33") == 0
323 || strcmp (result, "0xe.0000000000p-3 33") == 0);
324 ASSERT (retval == strlen (result));
327 { /* Large precision. */
330 my_snprintf (result, sizeof (result), "%.50a %d", 1.75, 33, 44, 55);
331 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
332 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
333 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
334 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
335 ASSERT (retval == strlen (result));
341 my_snprintf (result, sizeof (result), "%-10a %d", 1.75, 33, 44, 55);
342 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
343 || strcmp (result, "0x3.8p-1 33") == 0
344 || strcmp (result, "0x7p-2 33") == 0
345 || strcmp (result, "0xep-3 33") == 0);
346 ASSERT (retval == strlen (result));
349 { /* FLAG_SHOWSIGN. */
352 my_snprintf (result, sizeof (result), "%+a %d", 1.75, 33, 44, 55);
353 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
354 || strcmp (result, "+0x3.8p-1 33") == 0
355 || strcmp (result, "+0x7p-2 33") == 0
356 || strcmp (result, "+0xep-3 33") == 0);
357 ASSERT (retval == strlen (result));
363 my_snprintf (result, sizeof (result), "% a %d", 1.75, 33, 44, 55);
364 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
365 || strcmp (result, " 0x3.8p-1 33") == 0
366 || strcmp (result, " 0x7p-2 33") == 0
367 || strcmp (result, " 0xep-3 33") == 0);
368 ASSERT (retval == strlen (result));
374 my_snprintf (result, sizeof (result), "%#a %d", 1.75, 33, 44, 55);
375 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
376 || strcmp (result, "0x3.8p-1 33") == 0
377 || strcmp (result, "0x7.p-2 33") == 0
378 || strcmp (result, "0xe.p-3 33") == 0);
379 ASSERT (retval == strlen (result));
385 my_snprintf (result, sizeof (result), "%#a %d", 1.0, 33, 44, 55);
386 ASSERT (strcmp (result, "0x1.p+0 33") == 0
387 || strcmp (result, "0x2.p-1 33") == 0
388 || strcmp (result, "0x4.p-2 33") == 0
389 || strcmp (result, "0x8.p-3 33") == 0);
390 ASSERT (retval == strlen (result));
393 { /* FLAG_ZERO with finite number. */
396 my_snprintf (result, sizeof (result), "%010a %d", 1.75, 33, 44, 55);
397 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
398 || strcmp (result, "0x003.8p-1 33") == 0
399 || strcmp (result, "0x00007p-2 33") == 0
400 || strcmp (result, "0x0000ep-3 33") == 0);
401 ASSERT (retval == strlen (result));
404 { /* FLAG_ZERO with infinite number. */
407 my_snprintf (result, sizeof (result), "%010a %d", 1.0 / 0.0, 33, 44, 55);
408 /* "0000000inf 33" is not a valid result; see
409 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
410 ASSERT (strcmp (result, " inf 33") == 0);
411 ASSERT (retval == strlen (result));
414 { /* FLAG_ZERO with NaN. */
417 my_snprintf (result, sizeof (result), "%050a %d", NaNd (), 33, 44, 55);
418 /* "0000000nan 33" is not a valid result; see
419 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
420 ASSERT (strlen (result) == 50 + 3
421 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
422 && strcmp (result + strlen (result) - 3, " 33") == 0);
423 ASSERT (retval == strlen (result));
426 { /* A positive number. */
429 my_snprintf (result, sizeof (result), "%La %d", 3.1416015625L, 33, 44, 55);
430 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
431 || strcmp (result, "0x3.244p+0 33") == 0
432 || strcmp (result, "0x6.488p-1 33") == 0
433 || strcmp (result, "0xc.91p-2 33") == 0);
434 ASSERT (retval == strlen (result));
437 { /* A negative number. */
440 my_snprintf (result, sizeof (result), "%LA %d", -3.1416015625L, 33, 44, 55);
441 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
442 || strcmp (result, "-0X3.244P+0 33") == 0
443 || strcmp (result, "-0X6.488P-1 33") == 0
444 || strcmp (result, "-0XC.91P-2 33") == 0);
445 ASSERT (retval == strlen (result));
448 { /* Positive zero. */
451 my_snprintf (result, sizeof (result), "%La %d", 0.0L, 33, 44, 55);
452 ASSERT (strcmp (result, "0x0p+0 33") == 0);
453 ASSERT (retval == strlen (result));
456 { /* Negative zero. */
459 my_snprintf (result, sizeof (result), "%La %d", minus_zerol, 33, 44, 55);
460 if (have_minus_zero ())
461 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
462 ASSERT (retval == strlen (result));
465 { /* Positive infinity. */
468 my_snprintf (result, sizeof (result), "%La %d", 1.0L / 0.0L, 33, 44, 55);
469 ASSERT (strcmp (result, "inf 33") == 0);
470 ASSERT (retval == strlen (result));
473 { /* Negative infinity. */
476 my_snprintf (result, sizeof (result), "%La %d", -1.0L / 0.0L, 33, 44, 55);
477 ASSERT (strcmp (result, "-inf 33") == 0);
478 ASSERT (retval == strlen (result));
484 my_snprintf (result, sizeof (result), "%La %d", NaNl (), 33, 44, 55);
485 ASSERT (strlen (result) >= 3 + 3
486 && strisnan (result, 0, strlen (result) - 3, 0)
487 && strcmp (result + strlen (result) - 3, " 33") == 0);
488 ASSERT (retval == strlen (result));
490 #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_))
492 static union { unsigned int word[4]; long double value; } x =
493 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
496 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
497 ASSERT (strlen (result) >= 3 + 3
498 && strisnan (result, 0, strlen (result) - 3, 0)
499 && strcmp (result + strlen (result) - 3, " 33") == 0);
500 ASSERT (retval == strlen (result));
503 /* Signalling NaN. */
504 static union { unsigned int word[4]; long double value; } x =
505 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
508 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
509 ASSERT (strlen (result) >= 3 + 3
510 && strisnan (result, 0, strlen (result) - 3, 0)
511 && strcmp (result + strlen (result) - 3, " 33") == 0);
512 ASSERT (retval == strlen (result));
514 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
515 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
516 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
517 Application Architecture.
518 Table 5-2 "Floating-Point Register Encodings"
519 Figure 5-6 "Memory to Floating-Point Register Data Translation"
522 static union { unsigned int word[4]; long double value; } x =
523 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
526 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
527 ASSERT (strlen (result) >= 3 + 3
528 && strisnan (result, 0, strlen (result) - 3, 0)
529 && strcmp (result + strlen (result) - 3, " 33") == 0);
530 ASSERT (retval == strlen (result));
532 { /* Pseudo-Infinity. */
533 static union { unsigned int word[4]; long double value; } x =
534 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
537 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
538 ASSERT (strlen (result) >= 3 + 3
539 && strisnan (result, 0, strlen (result) - 3, 0)
540 && strcmp (result + strlen (result) - 3, " 33") == 0);
541 ASSERT (retval == strlen (result));
544 static union { unsigned int word[4]; long double value; } x =
545 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
548 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
549 ASSERT (strlen (result) >= 3 + 3
550 && strisnan (result, 0, strlen (result) - 3, 0)
551 && strcmp (result + strlen (result) - 3, " 33") == 0);
552 ASSERT (retval == strlen (result));
554 { /* Unnormalized number. */
555 static union { unsigned int word[4]; long double value; } x =
556 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
559 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
560 ASSERT (strlen (result) >= 3 + 3
561 && strisnan (result, 0, strlen (result) - 3, 0)
562 && strcmp (result + strlen (result) - 3, " 33") == 0);
563 ASSERT (retval == strlen (result));
565 { /* Pseudo-Denormal. */
566 static union { unsigned int word[4]; long double value; } x =
567 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
570 my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
571 ASSERT (strlen (result) >= 3 + 3
572 && strisnan (result, 0, strlen (result) - 3, 0)
573 && strcmp (result + strlen (result) - 3, " 33") == 0);
574 ASSERT (retval == strlen (result));
578 { /* Rounding near the decimal point. */
581 my_snprintf (result, sizeof (result), "%.0La %d", 1.5L, 33, 44, 55);
582 ASSERT (strcmp (result, "0x2p+0 33") == 0
583 || strcmp (result, "0x3p-1 33") == 0
584 || strcmp (result, "0x6p-2 33") == 0
585 || strcmp (result, "0xcp-3 33") == 0);
586 ASSERT (retval == strlen (result));
589 { /* Rounding with precision 0. */
592 my_snprintf (result, sizeof (result), "%.0La %d", 1.51L, 33, 44, 55);
593 ASSERT (strcmp (result, "0x2p+0 33") == 0
594 || strcmp (result, "0x3p-1 33") == 0
595 || strcmp (result, "0x6p-2 33") == 0
596 || strcmp (result, "0xcp-3 33") == 0);
597 ASSERT (retval == strlen (result));
600 { /* Rounding with precision 1. */
603 my_snprintf (result, sizeof (result), "%.1La %d", 1.51L, 33, 44, 55);
604 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
605 || strcmp (result, "0x3.0p-1 33") == 0
606 || strcmp (result, "0x6.1p-2 33") == 0
607 || strcmp (result, "0xc.1p-3 33") == 0);
608 ASSERT (retval == strlen (result));
611 { /* Rounding with precision 2. */
614 my_snprintf (result, sizeof (result), "%.2La %d", 1.51L, 33, 44, 55);
615 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
616 || strcmp (result, "0x3.05p-1 33") == 0
617 || strcmp (result, "0x6.0ap-2 33") == 0
618 || strcmp (result, "0xc.14p-3 33") == 0);
619 ASSERT (retval == strlen (result));
622 { /* Rounding with precision 3. */
625 my_snprintf (result, sizeof (result), "%.3La %d", 1.51L, 33, 44, 55);
626 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
627 || strcmp (result, "0x3.052p-1 33") == 0
628 || strcmp (result, "0x6.0a4p-2 33") == 0
629 || strcmp (result, "0xc.148p-3 33") == 0);
630 ASSERT (retval == strlen (result));
633 { /* Rounding can turn a ...FFF into a ...000. */
636 my_snprintf (result, sizeof (result), "%.3La %d", 1.49999L, 33, 44, 55);
637 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
638 || strcmp (result, "0x3.000p-1 33") == 0
639 || strcmp (result, "0x6.000p-2 33") == 0
640 || strcmp (result, "0xc.000p-3 33") == 0);
641 ASSERT (retval == strlen (result));
644 { /* Rounding can turn a ...FFF into a ...000.
645 This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
646 glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
649 my_snprintf (result, sizeof (result), "%.1La %d", 1.999L, 33, 44, 55);
650 ASSERT (strcmp (result, "0x1.0p+1 33") == 0
651 || strcmp (result, "0x2.0p+0 33") == 0
652 || strcmp (result, "0x4.0p-1 33") == 0
653 || strcmp (result, "0x8.0p-2 33") == 0);
654 ASSERT (retval == strlen (result));
660 my_snprintf (result, sizeof (result), "%10La %d", 1.75L, 33, 44, 55);
661 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
662 || strcmp (result, " 0x3.8p-1 33") == 0
663 || strcmp (result, " 0x7p-2 33") == 0
664 || strcmp (result, " 0xep-3 33") == 0);
665 ASSERT (retval == strlen (result));
668 { /* Small precision. */
671 my_snprintf (result, sizeof (result), "%.10La %d", 1.75L, 33, 44, 55);
672 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
673 || strcmp (result, "0x3.8000000000p-1 33") == 0
674 || strcmp (result, "0x7.0000000000p-2 33") == 0
675 || strcmp (result, "0xe.0000000000p-3 33") == 0);
676 ASSERT (retval == strlen (result));
679 { /* Large precision. */
682 my_snprintf (result, sizeof (result), "%.50La %d", 1.75L, 33, 44, 55);
683 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
684 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
685 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
686 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
687 ASSERT (retval == strlen (result));
693 my_snprintf (result, sizeof (result), "%-10La %d", 1.75L, 33, 44, 55);
694 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
695 || strcmp (result, "0x3.8p-1 33") == 0
696 || strcmp (result, "0x7p-2 33") == 0
697 || strcmp (result, "0xep-3 33") == 0);
698 ASSERT (retval == strlen (result));
701 { /* FLAG_SHOWSIGN. */
704 my_snprintf (result, sizeof (result), "%+La %d", 1.75L, 33, 44, 55);
705 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
706 || strcmp (result, "+0x3.8p-1 33") == 0
707 || strcmp (result, "+0x7p-2 33") == 0
708 || strcmp (result, "+0xep-3 33") == 0);
709 ASSERT (retval == strlen (result));
715 my_snprintf (result, sizeof (result), "% La %d", 1.75L, 33, 44, 55);
716 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
717 || strcmp (result, " 0x3.8p-1 33") == 0
718 || strcmp (result, " 0x7p-2 33") == 0
719 || strcmp (result, " 0xep-3 33") == 0);
720 ASSERT (retval == strlen (result));
726 my_snprintf (result, sizeof (result), "%#La %d", 1.75L, 33, 44, 55);
727 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
728 || strcmp (result, "0x3.8p-1 33") == 0
729 || strcmp (result, "0x7.p-2 33") == 0
730 || strcmp (result, "0xe.p-3 33") == 0);
731 ASSERT (retval == strlen (result));
737 my_snprintf (result, sizeof (result), "%#La %d", 1.0L, 33, 44, 55);
738 ASSERT (strcmp (result, "0x1.p+0 33") == 0
739 || strcmp (result, "0x2.p-1 33") == 0
740 || strcmp (result, "0x4.p-2 33") == 0
741 || strcmp (result, "0x8.p-3 33") == 0);
742 ASSERT (retval == strlen (result));
745 { /* FLAG_ZERO with finite number. */
748 my_snprintf (result, sizeof (result), "%010La %d", 1.75L, 33, 44, 55);
749 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
750 || strcmp (result, "0x003.8p-1 33") == 0
751 || strcmp (result, "0x00007p-2 33") == 0
752 || strcmp (result, "0x0000ep-3 33") == 0);
753 ASSERT (retval == strlen (result));
756 { /* FLAG_ZERO with infinite number. */
759 my_snprintf (result, sizeof (result), "%010La %d", 1.0L / 0.0L, 33, 44, 55);
760 /* "0000000inf 33" is not a valid result; see
761 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
762 ASSERT (strcmp (result, " inf 33") == 0);
763 ASSERT (retval == strlen (result));
766 { /* FLAG_ZERO with NaN. */
769 my_snprintf (result, sizeof (result), "%050La %d", NaNl (), 33, 44, 55);
770 /* "0000000nan 33" is not a valid result; see
771 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
772 ASSERT (strlen (result) == 50 + 3
773 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
774 && strcmp (result + strlen (result) - 3, " 33") == 0);
775 ASSERT (retval == strlen (result));
778 /* Test the support of the %f format directive. */
780 { /* A positive number. */
783 my_snprintf (result, sizeof (result), "%f %d", 12.75, 33, 44, 55);
784 ASSERT (strcmp (result, "12.750000 33") == 0);
785 ASSERT (retval == strlen (result));
788 { /* A larger positive number. */
791 my_snprintf (result, sizeof (result), "%f %d", 1234567.0, 33, 44, 55);
792 ASSERT (strcmp (result, "1234567.000000 33") == 0);
793 ASSERT (retval == strlen (result));
796 { /* Small and large positive numbers. */
797 static struct { double value; const char *string; } data[] =
799 { 1.234321234321234e-37, "0.000000" },
800 { 1.234321234321234e-36, "0.000000" },
801 { 1.234321234321234e-35, "0.000000" },
802 { 1.234321234321234e-34, "0.000000" },
803 { 1.234321234321234e-33, "0.000000" },
804 { 1.234321234321234e-32, "0.000000" },
805 { 1.234321234321234e-31, "0.000000" },
806 { 1.234321234321234e-30, "0.000000" },
807 { 1.234321234321234e-29, "0.000000" },
808 { 1.234321234321234e-28, "0.000000" },
809 { 1.234321234321234e-27, "0.000000" },
810 { 1.234321234321234e-26, "0.000000" },
811 { 1.234321234321234e-25, "0.000000" },
812 { 1.234321234321234e-24, "0.000000" },
813 { 1.234321234321234e-23, "0.000000" },
814 { 1.234321234321234e-22, "0.000000" },
815 { 1.234321234321234e-21, "0.000000" },
816 { 1.234321234321234e-20, "0.000000" },
817 { 1.234321234321234e-19, "0.000000" },
818 { 1.234321234321234e-18, "0.000000" },
819 { 1.234321234321234e-17, "0.000000" },
820 { 1.234321234321234e-16, "0.000000" },
821 { 1.234321234321234e-15, "0.000000" },
822 { 1.234321234321234e-14, "0.000000" },
823 { 1.234321234321234e-13, "0.000000" },
824 { 1.234321234321234e-12, "0.000000" },
825 { 1.234321234321234e-11, "0.000000" },
826 { 1.234321234321234e-10, "0.000000" },
827 { 1.234321234321234e-9, "0.000000" },
828 { 1.234321234321234e-8, "0.000000" },
829 { 1.234321234321234e-7, "0.000000" },
830 { 1.234321234321234e-6, "0.000001" },
831 { 1.234321234321234e-5, "0.000012" },
832 { 1.234321234321234e-4, "0.000123" },
833 { 1.234321234321234e-3, "0.001234" },
834 { 1.234321234321234e-2, "0.012343" },
835 { 1.234321234321234e-1, "0.123432" },
836 { 1.234321234321234, "1.234321" },
837 { 1.234321234321234e1, "12.343212" },
838 { 1.234321234321234e2, "123.432123" },
839 { 1.234321234321234e3, "1234.321234" },
840 { 1.234321234321234e4, "12343.212343" },
841 { 1.234321234321234e5, "123432.123432" },
842 { 1.234321234321234e6, "1234321.234321" },
843 { 1.234321234321234e7, "12343212.343212" },
844 { 1.234321234321234e8, "123432123.432123" },
845 { 1.234321234321234e9, "1234321234.321234" },
846 { 1.234321234321234e10, "12343212343.2123**" },
847 { 1.234321234321234e11, "123432123432.123***" },
848 { 1.234321234321234e12, "1234321234321.23****" },
849 { 1.234321234321234e13, "12343212343212.3*****" },
850 { 1.234321234321234e14, "123432123432123.******" },
851 { 1.234321234321234e15, "1234321234321234.000000" },
852 { 1.234321234321234e16, "123432123432123**.000000" },
853 { 1.234321234321234e17, "123432123432123***.000000" },
854 { 1.234321234321234e18, "123432123432123****.000000" },
855 { 1.234321234321234e19, "123432123432123*****.000000" },
856 { 1.234321234321234e20, "123432123432123******.000000" },
857 { 1.234321234321234e21, "123432123432123*******.000000" },
858 { 1.234321234321234e22, "123432123432123********.000000" },
859 { 1.234321234321234e23, "123432123432123*********.000000" },
860 { 1.234321234321234e24, "123432123432123**********.000000" },
861 { 1.234321234321234e25, "123432123432123***********.000000" },
862 { 1.234321234321234e26, "123432123432123************.000000" },
863 { 1.234321234321234e27, "123432123432123*************.000000" },
864 { 1.234321234321234e28, "123432123432123**************.000000" },
865 { 1.234321234321234e29, "123432123432123***************.000000" },
866 { 1.234321234321234e30, "123432123432123****************.000000" },
867 { 1.234321234321234e31, "123432123432123*****************.000000" },
868 { 1.234321234321234e32, "123432123432123******************.000000" },
869 { 1.234321234321234e33, "123432123432123*******************.000000" },
870 { 1.234321234321234e34, "123432123432123********************.000000" },
871 { 1.234321234321234e35, "123432123432123*********************.000000" },
872 { 1.234321234321234e36, "123432123432123**********************.000000" }
875 for (k = 0; k < SIZEOF (data); k++)
879 my_snprintf (result, sizeof (result), "%f", data[k].value);
880 ASSERT (strmatch (data[k].string, result));
881 ASSERT (retval == strlen (result));
885 { /* A negative number. */
888 my_snprintf (result, sizeof (result), "%f %d", -0.03125, 33, 44, 55);
889 ASSERT (strcmp (result, "-0.031250 33") == 0);
890 ASSERT (retval == strlen (result));
893 { /* Positive zero. */
896 my_snprintf (result, sizeof (result), "%f %d", 0.0, 33, 44, 55);
897 ASSERT (strcmp (result, "0.000000 33") == 0);
898 ASSERT (retval == strlen (result));
901 { /* Negative zero. */
904 my_snprintf (result, sizeof (result), "%f %d", -zerod, 33, 44, 55);
905 if (have_minus_zero ())
906 ASSERT (strcmp (result, "-0.000000 33") == 0);
907 ASSERT (retval == strlen (result));
910 { /* Positive infinity. */
913 my_snprintf (result, sizeof (result), "%f %d", 1.0 / 0.0, 33, 44, 55);
914 ASSERT (strcmp (result, "inf 33") == 0
915 || strcmp (result, "infinity 33") == 0);
916 ASSERT (retval == strlen (result));
919 { /* Negative infinity. */
922 my_snprintf (result, sizeof (result), "%f %d", -1.0 / 0.0, 33, 44, 55);
923 ASSERT (strcmp (result, "-inf 33") == 0
924 || strcmp (result, "-infinity 33") == 0);
925 ASSERT (retval == strlen (result));
931 my_snprintf (result, sizeof (result), "%f %d", NaNd (), 33, 44, 55);
932 ASSERT (strlen (result) >= 3 + 3
933 && strisnan (result, 0, strlen (result) - 3, 0)
934 && strcmp (result + strlen (result) - 3, " 33") == 0);
935 ASSERT (retval == strlen (result));
941 my_snprintf (result, sizeof (result), "%10f %d", 1.75, 33, 44, 55);
942 ASSERT (strcmp (result, " 1.750000 33") == 0);
943 ASSERT (retval == strlen (result));
949 my_snprintf (result, sizeof (result), "%-10f %d", 1.75, 33, 44, 55);
950 ASSERT (strcmp (result, "1.750000 33") == 0);
951 ASSERT (retval == strlen (result));
954 { /* FLAG_SHOWSIGN. */
957 my_snprintf (result, sizeof (result), "%+f %d", 1.75, 33, 44, 55);
958 ASSERT (strcmp (result, "+1.750000 33") == 0);
959 ASSERT (retval == strlen (result));
965 my_snprintf (result, sizeof (result), "% f %d", 1.75, 33, 44, 55);
966 ASSERT (strcmp (result, " 1.750000 33") == 0);
967 ASSERT (retval == strlen (result));
973 my_snprintf (result, sizeof (result), "%#f %d", 1.75, 33, 44, 55);
974 ASSERT (strcmp (result, "1.750000 33") == 0);
975 ASSERT (retval == strlen (result));
981 my_snprintf (result, sizeof (result), "%#.f %d", 1.75, 33, 44, 55);
982 ASSERT (strcmp (result, "2. 33") == 0);
983 ASSERT (retval == strlen (result));
986 { /* FLAG_ZERO with finite number. */
989 my_snprintf (result, sizeof (result), "%015f %d", 1234.0, 33, 44, 55);
990 ASSERT (strcmp (result, "00001234.000000 33") == 0);
991 ASSERT (retval == strlen (result));
994 { /* FLAG_ZERO with infinite number. */
997 my_snprintf (result, sizeof (result), "%015f %d", -1.0 / 0.0, 33, 44, 55);
998 ASSERT (strcmp (result, " -inf 33") == 0
999 || strcmp (result, " -infinity 33") == 0);
1000 ASSERT (retval == strlen (result));
1003 { /* FLAG_ZERO with NaN. */
1006 my_snprintf (result, sizeof (result), "%050f %d", NaNd (), 33, 44, 55);
1007 ASSERT (strlen (result) == 50 + 3
1008 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1009 && strcmp (result + strlen (result) - 3, " 33") == 0);
1010 ASSERT (retval == strlen (result));
1016 my_snprintf (result, sizeof (result), "%.f %d", 1234.0, 33, 44, 55);
1017 ASSERT (strcmp (result, "1234 33") == 0);
1018 ASSERT (retval == strlen (result));
1021 { /* Precision with no rounding. */
1024 my_snprintf (result, sizeof (result), "%.2f %d", 999.951, 33, 44, 55);
1025 ASSERT (strcmp (result, "999.95 33") == 0);
1026 ASSERT (retval == strlen (result));
1029 { /* Precision with rounding. */
1032 my_snprintf (result, sizeof (result), "%.2f %d", 999.996, 33, 44, 55);
1033 ASSERT (strcmp (result, "1000.00 33") == 0);
1034 ASSERT (retval == strlen (result));
1037 { /* A positive number. */
1040 my_snprintf (result, sizeof (result), "%Lf %d", 12.75L, 33, 44, 55);
1041 ASSERT (strcmp (result, "12.750000 33") == 0);
1042 ASSERT (retval == strlen (result));
1045 { /* A larger positive number. */
1048 my_snprintf (result, sizeof (result), "%Lf %d", 1234567.0L, 33, 44, 55);
1049 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1050 ASSERT (retval == strlen (result));
1053 { /* Small and large positive numbers. */
1054 static struct { long double value; const char *string; } data[] =
1056 { 1.234321234321234e-37L, "0.000000" },
1057 { 1.234321234321234e-36L, "0.000000" },
1058 { 1.234321234321234e-35L, "0.000000" },
1059 { 1.234321234321234e-34L, "0.000000" },
1060 { 1.234321234321234e-33L, "0.000000" },
1061 { 1.234321234321234e-32L, "0.000000" },
1062 { 1.234321234321234e-31L, "0.000000" },
1063 { 1.234321234321234e-30L, "0.000000" },
1064 { 1.234321234321234e-29L, "0.000000" },
1065 { 1.234321234321234e-28L, "0.000000" },
1066 { 1.234321234321234e-27L, "0.000000" },
1067 { 1.234321234321234e-26L, "0.000000" },
1068 { 1.234321234321234e-25L, "0.000000" },
1069 { 1.234321234321234e-24L, "0.000000" },
1070 { 1.234321234321234e-23L, "0.000000" },
1071 { 1.234321234321234e-22L, "0.000000" },
1072 { 1.234321234321234e-21L, "0.000000" },
1073 { 1.234321234321234e-20L, "0.000000" },
1074 { 1.234321234321234e-19L, "0.000000" },
1075 { 1.234321234321234e-18L, "0.000000" },
1076 { 1.234321234321234e-17L, "0.000000" },
1077 { 1.234321234321234e-16L, "0.000000" },
1078 { 1.234321234321234e-15L, "0.000000" },
1079 { 1.234321234321234e-14L, "0.000000" },
1080 { 1.234321234321234e-13L, "0.000000" },
1081 { 1.234321234321234e-12L, "0.000000" },
1082 { 1.234321234321234e-11L, "0.000000" },
1083 { 1.234321234321234e-10L, "0.000000" },
1084 { 1.234321234321234e-9L, "0.000000" },
1085 { 1.234321234321234e-8L, "0.000000" },
1086 { 1.234321234321234e-7L, "0.000000" },
1087 { 1.234321234321234e-6L, "0.000001" },
1088 { 1.234321234321234e-5L, "0.000012" },
1089 { 1.234321234321234e-4L, "0.000123" },
1090 { 1.234321234321234e-3L, "0.001234" },
1091 { 1.234321234321234e-2L, "0.012343" },
1092 { 1.234321234321234e-1L, "0.123432" },
1093 { 1.234321234321234L, "1.234321" },
1094 { 1.234321234321234e1L, "12.343212" },
1095 { 1.234321234321234e2L, "123.432123" },
1096 { 1.234321234321234e3L, "1234.321234" },
1097 { 1.234321234321234e4L, "12343.212343" },
1098 { 1.234321234321234e5L, "123432.123432" },
1099 { 1.234321234321234e6L, "1234321.234321" },
1100 { 1.234321234321234e7L, "12343212.343212" },
1101 { 1.234321234321234e8L, "123432123.432123" },
1102 { 1.234321234321234e9L, "1234321234.321234" },
1103 { 1.234321234321234e10L, "12343212343.2123**" },
1104 { 1.234321234321234e11L, "123432123432.123***" },
1105 { 1.234321234321234e12L, "1234321234321.23****" },
1106 { 1.234321234321234e13L, "12343212343212.3*****" },
1107 { 1.234321234321234e14L, "123432123432123.******" },
1108 { 1.234321234321234e15L, "1234321234321234.000000" },
1109 { 1.234321234321234e16L, "123432123432123**.000000" },
1110 { 1.234321234321234e17L, "123432123432123***.000000" },
1111 { 1.234321234321234e18L, "123432123432123****.000000" },
1112 { 1.234321234321234e19L, "123432123432123*****.000000" },
1113 { 1.234321234321234e20L, "123432123432123******.000000" },
1114 { 1.234321234321234e21L, "123432123432123*******.000000" },
1115 { 1.234321234321234e22L, "123432123432123********.000000" },
1116 { 1.234321234321234e23L, "123432123432123*********.000000" },
1117 { 1.234321234321234e24L, "123432123432123**********.000000" },
1118 { 1.234321234321234e25L, "123432123432123***********.000000" },
1119 { 1.234321234321234e26L, "123432123432123************.000000" },
1120 { 1.234321234321234e27L, "123432123432123*************.000000" },
1121 { 1.234321234321234e28L, "123432123432123**************.000000" },
1122 { 1.234321234321234e29L, "123432123432123***************.000000" },
1123 { 1.234321234321234e30L, "123432123432123****************.000000" },
1124 { 1.234321234321234e31L, "123432123432123*****************.000000" },
1125 { 1.234321234321234e32L, "123432123432123******************.000000" },
1126 { 1.234321234321234e33L, "123432123432123*******************.000000" },
1127 { 1.234321234321234e34L, "123432123432123********************.000000" },
1128 { 1.234321234321234e35L, "123432123432123*********************.000000" },
1129 { 1.234321234321234e36L, "123432123432123**********************.000000" }
1132 for (k = 0; k < SIZEOF (data); k++)
1136 my_snprintf (result, sizeof (result), "%Lf", data[k].value);
1137 ASSERT (strmatch (data[k].string, result));
1138 ASSERT (retval == strlen (result));
1142 { /* A negative number. */
1145 my_snprintf (result, sizeof (result), "%Lf %d", -0.03125L, 33, 44, 55);
1146 ASSERT (strcmp (result, "-0.031250 33") == 0);
1147 ASSERT (retval == strlen (result));
1150 { /* Positive zero. */
1153 my_snprintf (result, sizeof (result), "%Lf %d", 0.0L, 33, 44, 55);
1154 ASSERT (strcmp (result, "0.000000 33") == 0);
1155 ASSERT (retval == strlen (result));
1158 { /* Negative zero. */
1161 my_snprintf (result, sizeof (result), "%Lf %d", minus_zerol, 33, 44, 55);
1162 if (have_minus_zero ())
1163 ASSERT (strcmp (result, "-0.000000 33") == 0);
1164 ASSERT (retval == strlen (result));
1167 { /* Positive infinity. */
1170 my_snprintf (result, sizeof (result), "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
1171 ASSERT (strcmp (result, "inf 33") == 0
1172 || strcmp (result, "infinity 33") == 0);
1173 ASSERT (retval == strlen (result));
1176 { /* Negative infinity. */
1179 my_snprintf (result, sizeof (result), "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
1180 ASSERT (strcmp (result, "-inf 33") == 0
1181 || strcmp (result, "-infinity 33") == 0);
1182 ASSERT (retval == strlen (result));
1188 my_snprintf (result, sizeof (result), "%Lf %d", NaNl (), 33, 44, 55);
1189 ASSERT (strlen (result) >= 3 + 3
1190 && strisnan (result, 0, strlen (result) - 3, 0)
1191 && strcmp (result + strlen (result) - 3, " 33") == 0);
1192 ASSERT (retval == strlen (result));
1194 #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_))
1196 static union { unsigned int word[4]; long double value; } x =
1197 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
1200 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1201 ASSERT (strlen (result) >= 3 + 3
1202 && strisnan (result, 0, strlen (result) - 3, 0)
1203 && strcmp (result + strlen (result) - 3, " 33") == 0);
1204 ASSERT (retval == strlen (result));
1207 /* Signalling NaN. */
1208 static union { unsigned int word[4]; long double value; } x =
1209 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
1212 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1213 ASSERT (strlen (result) >= 3 + 3
1214 && strisnan (result, 0, strlen (result) - 3, 0)
1215 && strcmp (result + strlen (result) - 3, " 33") == 0);
1216 ASSERT (retval == strlen (result));
1218 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
1219 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
1220 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
1221 Application Architecture.
1222 Table 5-2 "Floating-Point Register Encodings"
1223 Figure 5-6 "Memory to Floating-Point Register Data Translation"
1226 static union { unsigned int word[4]; long double value; } x =
1227 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
1230 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1231 ASSERT (strlen (result) >= 3 + 3
1232 && strisnan (result, 0, strlen (result) - 3, 0)
1233 && strcmp (result + strlen (result) - 3, " 33") == 0);
1234 ASSERT (retval == strlen (result));
1236 { /* Pseudo-Infinity. */
1237 static union { unsigned int word[4]; long double value; } x =
1238 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
1241 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1242 ASSERT (strlen (result) >= 3 + 3
1243 && strisnan (result, 0, strlen (result) - 3, 0)
1244 && strcmp (result + strlen (result) - 3, " 33") == 0);
1245 ASSERT (retval == strlen (result));
1247 { /* Pseudo-Zero. */
1248 static union { unsigned int word[4]; long double value; } x =
1249 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
1252 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1253 ASSERT (strlen (result) >= 3 + 3
1254 && strisnan (result, 0, strlen (result) - 3, 0)
1255 && strcmp (result + strlen (result) - 3, " 33") == 0);
1256 ASSERT (retval == strlen (result));
1258 { /* Unnormalized number. */
1259 static union { unsigned int word[4]; long double value; } x =
1260 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
1263 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1264 ASSERT (strlen (result) >= 3 + 3
1265 && strisnan (result, 0, strlen (result) - 3, 0)
1266 && strcmp (result + strlen (result) - 3, " 33") == 0);
1267 ASSERT (retval == strlen (result));
1269 { /* Pseudo-Denormal. */
1270 static union { unsigned int word[4]; long double value; } x =
1271 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
1274 my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
1275 ASSERT (strlen (result) >= 3 + 3
1276 && strisnan (result, 0, strlen (result) - 3, 0)
1277 && strcmp (result + strlen (result) - 3, " 33") == 0);
1278 ASSERT (retval == strlen (result));
1285 my_snprintf (result, sizeof (result), "%10Lf %d", 1.75L, 33, 44, 55);
1286 ASSERT (strcmp (result, " 1.750000 33") == 0);
1287 ASSERT (retval == strlen (result));
1293 my_snprintf (result, sizeof (result), "%-10Lf %d", 1.75L, 33, 44, 55);
1294 ASSERT (strcmp (result, "1.750000 33") == 0);
1295 ASSERT (retval == strlen (result));
1298 { /* FLAG_SHOWSIGN. */
1301 my_snprintf (result, sizeof (result), "%+Lf %d", 1.75L, 33, 44, 55);
1302 ASSERT (strcmp (result, "+1.750000 33") == 0);
1303 ASSERT (retval == strlen (result));
1309 my_snprintf (result, sizeof (result), "% Lf %d", 1.75L, 33, 44, 55);
1310 ASSERT (strcmp (result, " 1.750000 33") == 0);
1311 ASSERT (retval == strlen (result));
1317 my_snprintf (result, sizeof (result), "%#Lf %d", 1.75L, 33, 44, 55);
1318 ASSERT (strcmp (result, "1.750000 33") == 0);
1319 ASSERT (retval == strlen (result));
1325 my_snprintf (result, sizeof (result), "%#.Lf %d", 1.75L, 33, 44, 55);
1326 ASSERT (strcmp (result, "2. 33") == 0);
1327 ASSERT (retval == strlen (result));
1330 { /* FLAG_ZERO with finite number. */
1333 my_snprintf (result, sizeof (result), "%015Lf %d", 1234.0L, 33, 44, 55);
1334 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1335 ASSERT (retval == strlen (result));
1338 { /* FLAG_ZERO with infinite number. */
1341 my_snprintf (result, sizeof (result), "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
1342 ASSERT (strcmp (result, " -inf 33") == 0
1343 || strcmp (result, " -infinity 33") == 0);
1344 ASSERT (retval == strlen (result));
1347 { /* FLAG_ZERO with NaN. */
1350 my_snprintf (result, sizeof (result), "%050Lf %d", NaNl (), 33, 44, 55);
1351 ASSERT (strlen (result) == 50 + 3
1352 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1353 && strcmp (result + strlen (result) - 3, " 33") == 0);
1354 ASSERT (retval == strlen (result));
1360 my_snprintf (result, sizeof (result), "%.Lf %d", 1234.0L, 33, 44, 55);
1361 ASSERT (strcmp (result, "1234 33") == 0);
1362 ASSERT (retval == strlen (result));
1365 { /* Precision with no rounding. */
1368 my_snprintf (result, sizeof (result), "%.2Lf %d", 999.951L, 33, 44, 55);
1369 ASSERT (strcmp (result, "999.95 33") == 0);
1370 ASSERT (retval == strlen (result));
1373 { /* Precision with rounding. */
1376 my_snprintf (result, sizeof (result), "%.2Lf %d", 999.996L, 33, 44, 55);
1377 ASSERT (strcmp (result, "1000.00 33") == 0);
1378 ASSERT (retval == strlen (result));
1381 /* Test the support of the %F format directive. */
1383 { /* A positive number. */
1386 my_snprintf (result, sizeof (result), "%F %d", 12.75, 33, 44, 55);
1387 ASSERT (strcmp (result, "12.750000 33") == 0);
1388 ASSERT (retval == strlen (result));
1391 { /* A larger positive number. */
1394 my_snprintf (result, sizeof (result), "%F %d", 1234567.0, 33, 44, 55);
1395 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1396 ASSERT (retval == strlen (result));
1399 { /* A negative number. */
1402 my_snprintf (result, sizeof (result), "%F %d", -0.03125, 33, 44, 55);
1403 ASSERT (strcmp (result, "-0.031250 33") == 0);
1404 ASSERT (retval == strlen (result));
1407 { /* Positive zero. */
1410 my_snprintf (result, sizeof (result), "%F %d", 0.0, 33, 44, 55);
1411 ASSERT (strcmp (result, "0.000000 33") == 0);
1412 ASSERT (retval == strlen (result));
1415 { /* Negative zero. */
1418 my_snprintf (result, sizeof (result), "%F %d", -zerod, 33, 44, 55);
1419 if (have_minus_zero ())
1420 ASSERT (strcmp (result, "-0.000000 33") == 0);
1421 ASSERT (retval == strlen (result));
1424 { /* Positive infinity. */
1427 my_snprintf (result, sizeof (result), "%F %d", 1.0 / 0.0, 33, 44, 55);
1428 ASSERT (strcmp (result, "INF 33") == 0
1429 || strcmp (result, "INFINITY 33") == 0);
1430 ASSERT (retval == strlen (result));
1433 { /* Negative infinity. */
1436 my_snprintf (result, sizeof (result), "%F %d", -1.0 / 0.0, 33, 44, 55);
1437 ASSERT (strcmp (result, "-INF 33") == 0
1438 || strcmp (result, "-INFINITY 33") == 0);
1439 ASSERT (retval == strlen (result));
1445 my_snprintf (result, sizeof (result), "%F %d", NaNd (), 33, 44, 55);
1446 ASSERT (strlen (result) >= 3 + 3
1447 && strisnan (result, 0, strlen (result) - 3, 1)
1448 && strcmp (result + strlen (result) - 3, " 33") == 0);
1449 ASSERT (retval == strlen (result));
1455 my_snprintf (result, sizeof (result), "%015F %d", 1234.0, 33, 44, 55);
1456 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1457 ASSERT (retval == strlen (result));
1460 { /* FLAG_ZERO with infinite number. */
1463 my_snprintf (result, sizeof (result), "%015F %d", -1.0 / 0.0, 33, 44, 55);
1464 ASSERT (strcmp (result, " -INF 33") == 0
1465 || strcmp (result, " -INFINITY 33") == 0);
1466 ASSERT (retval == strlen (result));
1472 my_snprintf (result, sizeof (result), "%.F %d", 1234.0, 33, 44, 55);
1473 ASSERT (strcmp (result, "1234 33") == 0);
1474 ASSERT (retval == strlen (result));
1477 { /* Precision with no rounding. */
1480 my_snprintf (result, sizeof (result), "%.2F %d", 999.951, 33, 44, 55);
1481 ASSERT (strcmp (result, "999.95 33") == 0);
1482 ASSERT (retval == strlen (result));
1485 { /* Precision with rounding. */
1488 my_snprintf (result, sizeof (result), "%.2F %d", 999.996, 33, 44, 55);
1489 ASSERT (strcmp (result, "1000.00 33") == 0);
1490 ASSERT (retval == strlen (result));
1493 { /* A positive number. */
1496 my_snprintf (result, sizeof (result), "%LF %d", 12.75L, 33, 44, 55);
1497 ASSERT (strcmp (result, "12.750000 33") == 0);
1498 ASSERT (retval == strlen (result));
1501 { /* A larger positive number. */
1504 my_snprintf (result, sizeof (result), "%LF %d", 1234567.0L, 33, 44, 55);
1505 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1506 ASSERT (retval == strlen (result));
1509 { /* A negative number. */
1512 my_snprintf (result, sizeof (result), "%LF %d", -0.03125L, 33, 44, 55);
1513 ASSERT (strcmp (result, "-0.031250 33") == 0);
1514 ASSERT (retval == strlen (result));
1517 { /* Positive zero. */
1520 my_snprintf (result, sizeof (result), "%LF %d", 0.0L, 33, 44, 55);
1521 ASSERT (strcmp (result, "0.000000 33") == 0);
1522 ASSERT (retval == strlen (result));
1525 { /* Negative zero. */
1528 my_snprintf (result, sizeof (result), "%LF %d", minus_zerol, 33, 44, 55);
1529 if (have_minus_zero ())
1530 ASSERT (strcmp (result, "-0.000000 33") == 0);
1531 ASSERT (retval == strlen (result));
1534 { /* Positive infinity. */
1537 my_snprintf (result, sizeof (result), "%LF %d", 1.0L / 0.0L, 33, 44, 55);
1538 ASSERT (strcmp (result, "INF 33") == 0
1539 || strcmp (result, "INFINITY 33") == 0);
1540 ASSERT (retval == strlen (result));
1543 { /* Negative infinity. */
1546 my_snprintf (result, sizeof (result), "%LF %d", -1.0L / 0.0L, 33, 44, 55);
1547 ASSERT (strcmp (result, "-INF 33") == 0
1548 || strcmp (result, "-INFINITY 33") == 0);
1549 ASSERT (retval == strlen (result));
1555 my_snprintf (result, sizeof (result), "%LF %d", NaNl (), 33, 44, 55);
1556 ASSERT (strlen (result) >= 3 + 3
1557 && strisnan (result, 0, strlen (result) - 3, 1)
1558 && strcmp (result + strlen (result) - 3, " 33") == 0);
1559 ASSERT (retval == strlen (result));
1565 my_snprintf (result, sizeof (result), "%015LF %d", 1234.0L, 33, 44, 55);
1566 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1567 ASSERT (retval == strlen (result));
1570 { /* FLAG_ZERO with infinite number. */
1573 my_snprintf (result, sizeof (result), "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
1574 ASSERT (strcmp (result, " -INF 33") == 0
1575 || strcmp (result, " -INFINITY 33") == 0);
1576 ASSERT (retval == strlen (result));
1582 my_snprintf (result, sizeof (result), "%.LF %d", 1234.0L, 33, 44, 55);
1583 ASSERT (strcmp (result, "1234 33") == 0);
1584 ASSERT (retval == strlen (result));
1587 { /* Precision with no rounding. */
1590 my_snprintf (result, sizeof (result), "%.2LF %d", 999.951L, 33, 44, 55);
1591 ASSERT (strcmp (result, "999.95 33") == 0);
1592 ASSERT (retval == strlen (result));
1595 { /* Precision with rounding. */
1598 my_snprintf (result, sizeof (result), "%.2LF %d", 999.996L, 33, 44, 55);
1599 ASSERT (strcmp (result, "1000.00 33") == 0);
1600 ASSERT (retval == strlen (result));
1603 /* Test the support of the %e format directive. */
1605 { /* A positive number. */
1608 my_snprintf (result, sizeof (result), "%e %d", 12.75, 33, 44, 55);
1609 ASSERT (strcmp (result, "1.275000e+01 33") == 0
1610 || strcmp (result, "1.275000e+001 33") == 0);
1611 ASSERT (retval == strlen (result));
1614 { /* A larger positive number. */
1617 my_snprintf (result, sizeof (result), "%e %d", 1234567.0, 33, 44, 55);
1618 ASSERT (strcmp (result, "1.234567e+06 33") == 0
1619 || strcmp (result, "1.234567e+006 33") == 0);
1620 ASSERT (retval == strlen (result));
1623 { /* Small and large positive numbers. */
1624 static struct { double value; const char *string; } data[] =
1626 { 1.234321234321234e-37, "1.234321e-37" },
1627 { 1.234321234321234e-36, "1.234321e-36" },
1628 { 1.234321234321234e-35, "1.234321e-35" },
1629 { 1.234321234321234e-34, "1.234321e-34" },
1630 { 1.234321234321234e-33, "1.234321e-33" },
1631 { 1.234321234321234e-32, "1.234321e-32" },
1632 { 1.234321234321234e-31, "1.234321e-31" },
1633 { 1.234321234321234e-30, "1.234321e-30" },
1634 { 1.234321234321234e-29, "1.234321e-29" },
1635 { 1.234321234321234e-28, "1.234321e-28" },
1636 { 1.234321234321234e-27, "1.234321e-27" },
1637 { 1.234321234321234e-26, "1.234321e-26" },
1638 { 1.234321234321234e-25, "1.234321e-25" },
1639 { 1.234321234321234e-24, "1.234321e-24" },
1640 { 1.234321234321234e-23, "1.234321e-23" },
1641 { 1.234321234321234e-22, "1.234321e-22" },
1642 { 1.234321234321234e-21, "1.234321e-21" },
1643 { 1.234321234321234e-20, "1.234321e-20" },
1644 { 1.234321234321234e-19, "1.234321e-19" },
1645 { 1.234321234321234e-18, "1.234321e-18" },
1646 { 1.234321234321234e-17, "1.234321e-17" },
1647 { 1.234321234321234e-16, "1.234321e-16" },
1648 { 1.234321234321234e-15, "1.234321e-15" },
1649 { 1.234321234321234e-14, "1.234321e-14" },
1650 { 1.234321234321234e-13, "1.234321e-13" },
1651 { 1.234321234321234e-12, "1.234321e-12" },
1652 { 1.234321234321234e-11, "1.234321e-11" },
1653 { 1.234321234321234e-10, "1.234321e-10" },
1654 { 1.234321234321234e-9, "1.234321e-09" },
1655 { 1.234321234321234e-8, "1.234321e-08" },
1656 { 1.234321234321234e-7, "1.234321e-07" },
1657 { 1.234321234321234e-6, "1.234321e-06" },
1658 { 1.234321234321234e-5, "1.234321e-05" },
1659 { 1.234321234321234e-4, "1.234321e-04" },
1660 { 1.234321234321234e-3, "1.234321e-03" },
1661 { 1.234321234321234e-2, "1.234321e-02" },
1662 { 1.234321234321234e-1, "1.234321e-01" },
1663 { 1.234321234321234, "1.234321e+00" },
1664 { 1.234321234321234e1, "1.234321e+01" },
1665 { 1.234321234321234e2, "1.234321e+02" },
1666 { 1.234321234321234e3, "1.234321e+03" },
1667 { 1.234321234321234e4, "1.234321e+04" },
1668 { 1.234321234321234e5, "1.234321e+05" },
1669 { 1.234321234321234e6, "1.234321e+06" },
1670 { 1.234321234321234e7, "1.234321e+07" },
1671 { 1.234321234321234e8, "1.234321e+08" },
1672 { 1.234321234321234e9, "1.234321e+09" },
1673 { 1.234321234321234e10, "1.234321e+10" },
1674 { 1.234321234321234e11, "1.234321e+11" },
1675 { 1.234321234321234e12, "1.234321e+12" },
1676 { 1.234321234321234e13, "1.234321e+13" },
1677 { 1.234321234321234e14, "1.234321e+14" },
1678 { 1.234321234321234e15, "1.234321e+15" },
1679 { 1.234321234321234e16, "1.234321e+16" },
1680 { 1.234321234321234e17, "1.234321e+17" },
1681 { 1.234321234321234e18, "1.234321e+18" },
1682 { 1.234321234321234e19, "1.234321e+19" },
1683 { 1.234321234321234e20, "1.234321e+20" },
1684 { 1.234321234321234e21, "1.234321e+21" },
1685 { 1.234321234321234e22, "1.234321e+22" },
1686 { 1.234321234321234e23, "1.234321e+23" },
1687 { 1.234321234321234e24, "1.234321e+24" },
1688 { 1.234321234321234e25, "1.234321e+25" },
1689 { 1.234321234321234e26, "1.234321e+26" },
1690 { 1.234321234321234e27, "1.234321e+27" },
1691 { 1.234321234321234e28, "1.234321e+28" },
1692 { 1.234321234321234e29, "1.234321e+29" },
1693 { 1.234321234321234e30, "1.234321e+30" },
1694 { 1.234321234321234e31, "1.234321e+31" },
1695 { 1.234321234321234e32, "1.234321e+32" },
1696 { 1.234321234321234e33, "1.234321e+33" },
1697 { 1.234321234321234e34, "1.234321e+34" },
1698 { 1.234321234321234e35, "1.234321e+35" },
1699 { 1.234321234321234e36, "1.234321e+36" }
1702 for (k = 0; k < SIZEOF (data); k++)
1706 my_snprintf (result, sizeof (result), "%e", data[k].value);
1707 const char *expected = data[k].string;
1708 ASSERT (strcmp (result, expected) == 0
1709 /* Some implementations produce exponents with 3 digits. */
1710 || (strlen (result) == strlen (expected) + 1
1711 && memcmp (result, expected, strlen (expected) - 2) == 0
1712 && result[strlen (expected) - 2] == '0'
1713 && strcmp (result + strlen (expected) - 1,
1714 expected + strlen (expected) - 2)
1716 ASSERT (retval == strlen (result));
1720 { /* A negative number. */
1723 my_snprintf (result, sizeof (result), "%e %d", -0.03125, 33, 44, 55);
1724 ASSERT (strcmp (result, "-3.125000e-02 33") == 0
1725 || strcmp (result, "-3.125000e-002 33") == 0);
1726 ASSERT (retval == strlen (result));
1729 { /* Positive zero. */
1732 my_snprintf (result, sizeof (result), "%e %d", 0.0, 33, 44, 55);
1733 ASSERT (strcmp (result, "0.000000e+00 33") == 0
1734 || strcmp (result, "0.000000e+000 33") == 0);
1735 ASSERT (retval == strlen (result));
1738 { /* Negative zero. */
1741 my_snprintf (result, sizeof (result), "%e %d", -zerod, 33, 44, 55);
1742 if (have_minus_zero ())
1743 ASSERT (strcmp (result, "-0.000000e+00 33") == 0
1744 || strcmp (result, "-0.000000e+000 33") == 0);
1745 ASSERT (retval == strlen (result));
1748 { /* Positive infinity. */
1751 my_snprintf (result, sizeof (result), "%e %d", 1.0 / 0.0, 33, 44, 55);
1752 ASSERT (strcmp (result, "inf 33") == 0
1753 || strcmp (result, "infinity 33") == 0);
1754 ASSERT (retval == strlen (result));
1757 { /* Negative infinity. */
1760 my_snprintf (result, sizeof (result), "%e %d", -1.0 / 0.0, 33, 44, 55);
1761 ASSERT (strcmp (result, "-inf 33") == 0
1762 || strcmp (result, "-infinity 33") == 0);
1763 ASSERT (retval == strlen (result));
1769 my_snprintf (result, sizeof (result), "%e %d", NaNd (), 33, 44, 55);
1770 ASSERT (strlen (result) >= 3 + 3
1771 && strisnan (result, 0, strlen (result) - 3, 0)
1772 && strcmp (result + strlen (result) - 3, " 33") == 0);
1773 ASSERT (retval == strlen (result));
1779 my_snprintf (result, sizeof (result), "%15e %d", 1.75, 33, 44, 55);
1780 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
1781 || strcmp (result, " 1.750000e+000 33") == 0);
1782 ASSERT (retval == strlen (result));
1788 my_snprintf (result, sizeof (result), "%-15e %d", 1.75, 33, 44, 55);
1789 ASSERT (strcmp (result, "1.750000e+00 33") == 0
1790 || strcmp (result, "1.750000e+000 33") == 0);
1791 ASSERT (retval == strlen (result));
1794 { /* FLAG_SHOWSIGN. */
1797 my_snprintf (result, sizeof (result), "%+e %d", 1.75, 33, 44, 55);
1798 ASSERT (strcmp (result, "+1.750000e+00 33") == 0
1799 || strcmp (result, "+1.750000e+000 33") == 0);
1800 ASSERT (retval == strlen (result));
1806 my_snprintf (result, sizeof (result), "% e %d", 1.75, 33, 44, 55);
1807 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
1808 || strcmp (result, " 1.750000e+000 33") == 0);
1809 ASSERT (retval == strlen (result));
1815 my_snprintf (result, sizeof (result), "%#e %d", 1.75, 33, 44, 55);
1816 ASSERT (strcmp (result, "1.750000e+00 33") == 0
1817 || strcmp (result, "1.750000e+000 33") == 0);
1818 ASSERT (retval == strlen (result));
1824 my_snprintf (result, sizeof (result), "%#.e %d", 1.75, 33, 44, 55);
1825 ASSERT (strcmp (result, "2.e+00 33") == 0
1826 || strcmp (result, "2.e+000 33") == 0);
1827 ASSERT (retval == strlen (result));
1833 my_snprintf (result, sizeof (result), "%#.e %d", 9.75, 33, 44, 55);
1834 ASSERT (strcmp (result, "1.e+01 33") == 0
1835 || strcmp (result, "1.e+001 33") == 0);
1836 ASSERT (retval == strlen (result));
1839 { /* FLAG_ZERO with finite number. */
1842 my_snprintf (result, sizeof (result), "%015e %d", 1234.0, 33, 44, 55);
1843 ASSERT (strcmp (result, "0001.234000e+03 33") == 0
1844 || strcmp (result, "001.234000e+003 33") == 0);
1845 ASSERT (retval == strlen (result));
1848 { /* FLAG_ZERO with infinite number. */
1851 my_snprintf (result, sizeof (result), "%015e %d", -1.0 / 0.0, 33, 44, 55);
1852 ASSERT (strcmp (result, " -inf 33") == 0
1853 || strcmp (result, " -infinity 33") == 0);
1854 ASSERT (retval == strlen (result));
1857 { /* FLAG_ZERO with NaN. */
1860 my_snprintf (result, sizeof (result), "%050e %d", NaNd (), 33, 44, 55);
1861 ASSERT (strlen (result) == 50 + 3
1862 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1863 && strcmp (result + strlen (result) - 3, " 33") == 0);
1864 ASSERT (retval == strlen (result));
1870 my_snprintf (result, sizeof (result), "%.e %d", 1234.0, 33, 44, 55);
1871 ASSERT (strcmp (result, "1e+03 33") == 0
1872 || strcmp (result, "1e+003 33") == 0);
1873 ASSERT (retval == strlen (result));
1876 { /* Precision with no rounding. */
1879 my_snprintf (result, sizeof (result), "%.4e %d", 999.951, 33, 44, 55);
1880 ASSERT (strcmp (result, "9.9995e+02 33") == 0
1881 || strcmp (result, "9.9995e+002 33") == 0);
1882 ASSERT (retval == strlen (result));
1885 { /* Precision with rounding. */
1888 my_snprintf (result, sizeof (result), "%.4e %d", 999.996, 33, 44, 55);
1889 ASSERT (strcmp (result, "1.0000e+03 33") == 0
1890 || strcmp (result, "1.0000e+003 33") == 0);
1891 ASSERT (retval == strlen (result));
1894 { /* A positive number. */
1897 my_snprintf (result, sizeof (result), "%Le %d", 12.75L, 33, 44, 55);
1898 ASSERT (strcmp (result, "1.275000e+01 33") == 0
1899 || strcmp (result, "1.275000e+001 33") == 0);
1900 ASSERT (retval == strlen (result));
1903 { /* A larger positive number. */
1906 my_snprintf (result, sizeof (result), "%Le %d", 1234567.0L, 33, 44, 55);
1907 ASSERT (strcmp (result, "1.234567e+06 33") == 0
1908 || strcmp (result, "1.234567e+006 33") == 0);
1909 ASSERT (retval == strlen (result));
1912 { /* Small and large positive numbers. */
1913 static struct { long double value; const char *string; } data[] =
1915 { 1.234321234321234e-37L, "1.234321e-37" },
1916 { 1.234321234321234e-36L, "1.234321e-36" },
1917 { 1.234321234321234e-35L, "1.234321e-35" },
1918 { 1.234321234321234e-34L, "1.234321e-34" },
1919 { 1.234321234321234e-33L, "1.234321e-33" },
1920 { 1.234321234321234e-32L, "1.234321e-32" },
1921 { 1.234321234321234e-31L, "1.234321e-31" },
1922 { 1.234321234321234e-30L, "1.234321e-30" },
1923 { 1.234321234321234e-29L, "1.234321e-29" },
1924 { 1.234321234321234e-28L, "1.234321e-28" },
1925 { 1.234321234321234e-27L, "1.234321e-27" },
1926 { 1.234321234321234e-26L, "1.234321e-26" },
1927 { 1.234321234321234e-25L, "1.234321e-25" },
1928 { 1.234321234321234e-24L, "1.234321e-24" },
1929 { 1.234321234321234e-23L, "1.234321e-23" },
1930 { 1.234321234321234e-22L, "1.234321e-22" },
1931 { 1.234321234321234e-21L, "1.234321e-21" },
1932 { 1.234321234321234e-20L, "1.234321e-20" },
1933 { 1.234321234321234e-19L, "1.234321e-19" },
1934 { 1.234321234321234e-18L, "1.234321e-18" },
1935 { 1.234321234321234e-17L, "1.234321e-17" },
1936 { 1.234321234321234e-16L, "1.234321e-16" },
1937 { 1.234321234321234e-15L, "1.234321e-15" },
1938 { 1.234321234321234e-14L, "1.234321e-14" },
1939 { 1.234321234321234e-13L, "1.234321e-13" },
1940 { 1.234321234321234e-12L, "1.234321e-12" },
1941 { 1.234321234321234e-11L, "1.234321e-11" },
1942 { 1.234321234321234e-10L, "1.234321e-10" },
1943 { 1.234321234321234e-9L, "1.234321e-09" },
1944 { 1.234321234321234e-8L, "1.234321e-08" },
1945 { 1.234321234321234e-7L, "1.234321e-07" },
1946 { 1.234321234321234e-6L, "1.234321e-06" },
1947 { 1.234321234321234e-5L, "1.234321e-05" },
1948 { 1.234321234321234e-4L, "1.234321e-04" },
1949 { 1.234321234321234e-3L, "1.234321e-03" },
1950 { 1.234321234321234e-2L, "1.234321e-02" },
1951 { 1.234321234321234e-1L, "1.234321e-01" },
1952 { 1.234321234321234L, "1.234321e+00" },
1953 { 1.234321234321234e1L, "1.234321e+01" },
1954 { 1.234321234321234e2L, "1.234321e+02" },
1955 { 1.234321234321234e3L, "1.234321e+03" },
1956 { 1.234321234321234e4L, "1.234321e+04" },
1957 { 1.234321234321234e5L, "1.234321e+05" },
1958 { 1.234321234321234e6L, "1.234321e+06" },
1959 { 1.234321234321234e7L, "1.234321e+07" },
1960 { 1.234321234321234e8L, "1.234321e+08" },
1961 { 1.234321234321234e9L, "1.234321e+09" },
1962 { 1.234321234321234e10L, "1.234321e+10" },
1963 { 1.234321234321234e11L, "1.234321e+11" },
1964 { 1.234321234321234e12L, "1.234321e+12" },
1965 { 1.234321234321234e13L, "1.234321e+13" },
1966 { 1.234321234321234e14L, "1.234321e+14" },
1967 { 1.234321234321234e15L, "1.234321e+15" },
1968 { 1.234321234321234e16L, "1.234321e+16" },
1969 { 1.234321234321234e17L, "1.234321e+17" },
1970 { 1.234321234321234e18L, "1.234321e+18" },
1971 { 1.234321234321234e19L, "1.234321e+19" },
1972 { 1.234321234321234e20L, "1.234321e+20" },
1973 { 1.234321234321234e21L, "1.234321e+21" },
1974 { 1.234321234321234e22L, "1.234321e+22" },
1975 { 1.234321234321234e23L, "1.234321e+23" },
1976 { 1.234321234321234e24L, "1.234321e+24" },
1977 { 1.234321234321234e25L, "1.234321e+25" },
1978 { 1.234321234321234e26L, "1.234321e+26" },
1979 { 1.234321234321234e27L, "1.234321e+27" },
1980 { 1.234321234321234e28L, "1.234321e+28" },
1981 { 1.234321234321234e29L, "1.234321e+29" },
1982 { 1.234321234321234e30L, "1.234321e+30" },
1983 { 1.234321234321234e31L, "1.234321e+31" },
1984 { 1.234321234321234e32L, "1.234321e+32" },
1985 { 1.234321234321234e33L, "1.234321e+33" },
1986 { 1.234321234321234e34L, "1.234321e+34" },
1987 { 1.234321234321234e35L, "1.234321e+35" },
1988 { 1.234321234321234e36L, "1.234321e+36" }
1991 for (k = 0; k < SIZEOF (data); k++)
1995 my_snprintf (result, sizeof (result), "%Le", data[k].value);
1996 const char *expected = data[k].string;
1997 ASSERT (strcmp (result, expected) == 0
1998 /* Some implementations produce exponents with 3 digits. */
1999 || (strlen (result) == strlen (expected) + 1
2000 && memcmp (result, expected, strlen (expected) - 2) == 0
2001 && result[strlen (expected) - 2] == '0'
2002 && strcmp (result + strlen (expected) - 1,
2003 expected + strlen (expected) - 2)
2005 ASSERT (retval == strlen (result));
2009 { /* A negative number. */
2012 my_snprintf (result, sizeof (result), "%Le %d", -0.03125L, 33, 44, 55);
2013 ASSERT (strcmp (result, "-3.125000e-02 33") == 0
2014 || strcmp (result, "-3.125000e-002 33") == 0);
2015 ASSERT (retval == strlen (result));
2018 { /* Positive zero. */
2021 my_snprintf (result, sizeof (result), "%Le %d", 0.0L, 33, 44, 55);
2022 ASSERT (strcmp (result, "0.000000e+00 33") == 0
2023 || strcmp (result, "0.000000e+000 33") == 0);
2024 ASSERT (retval == strlen (result));
2027 { /* Negative zero. */
2030 my_snprintf (result, sizeof (result), "%Le %d", minus_zerol, 33, 44, 55);
2031 if (have_minus_zero ())
2032 ASSERT (strcmp (result, "-0.000000e+00 33") == 0
2033 || strcmp (result, "-0.000000e+000 33") == 0);
2034 ASSERT (retval == strlen (result));
2037 { /* Positive infinity. */
2040 my_snprintf (result, sizeof (result), "%Le %d", 1.0L / 0.0L, 33, 44, 55);
2041 ASSERT (strcmp (result, "inf 33") == 0
2042 || strcmp (result, "infinity 33") == 0);
2043 ASSERT (retval == strlen (result));
2046 { /* Negative infinity. */
2049 my_snprintf (result, sizeof (result), "%Le %d", -1.0L / 0.0L, 33, 44, 55);
2050 ASSERT (strcmp (result, "-inf 33") == 0
2051 || strcmp (result, "-infinity 33") == 0);
2052 ASSERT (retval == strlen (result));
2058 my_snprintf (result, sizeof (result), "%Le %d", NaNl (), 33, 44, 55);
2059 ASSERT (strlen (result) >= 3 + 3
2060 && strisnan (result, 0, strlen (result) - 3, 0)
2061 && strcmp (result + strlen (result) - 3, " 33") == 0);
2062 ASSERT (retval == strlen (result));
2064 #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_))
2066 static union { unsigned int word[4]; long double value; } x =
2067 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
2070 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2071 ASSERT (strlen (result) >= 3 + 3
2072 && strisnan (result, 0, strlen (result) - 3, 0)
2073 && strcmp (result + strlen (result) - 3, " 33") == 0);
2074 ASSERT (retval == strlen (result));
2077 /* Signalling NaN. */
2078 static union { unsigned int word[4]; long double value; } x =
2079 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
2082 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2083 ASSERT (strlen (result) >= 3 + 3
2084 && strisnan (result, 0, strlen (result) - 3, 0)
2085 && strcmp (result + strlen (result) - 3, " 33") == 0);
2086 ASSERT (retval == strlen (result));
2088 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
2089 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
2090 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
2091 Application Architecture.
2092 Table 5-2 "Floating-Point Register Encodings"
2093 Figure 5-6 "Memory to Floating-Point Register Data Translation"
2096 static union { unsigned int word[4]; long double value; } x =
2097 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
2100 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2101 ASSERT (strlen (result) >= 3 + 3
2102 && strisnan (result, 0, strlen (result) - 3, 0)
2103 && strcmp (result + strlen (result) - 3, " 33") == 0);
2104 ASSERT (retval == strlen (result));
2106 { /* Pseudo-Infinity. */
2107 static union { unsigned int word[4]; long double value; } x =
2108 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
2111 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2112 ASSERT (strlen (result) >= 3 + 3
2113 && strisnan (result, 0, strlen (result) - 3, 0)
2114 && strcmp (result + strlen (result) - 3, " 33") == 0);
2115 ASSERT (retval == strlen (result));
2117 { /* Pseudo-Zero. */
2118 static union { unsigned int word[4]; long double value; } x =
2119 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
2122 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2123 ASSERT (strlen (result) >= 3 + 3
2124 && strisnan (result, 0, strlen (result) - 3, 0)
2125 && strcmp (result + strlen (result) - 3, " 33") == 0);
2126 ASSERT (retval == strlen (result));
2128 { /* Unnormalized number. */
2129 static union { unsigned int word[4]; long double value; } x =
2130 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
2133 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2134 ASSERT (strlen (result) >= 3 + 3
2135 && strisnan (result, 0, strlen (result) - 3, 0)
2136 && strcmp (result + strlen (result) - 3, " 33") == 0);
2137 ASSERT (retval == strlen (result));
2139 { /* Pseudo-Denormal. */
2140 static union { unsigned int word[4]; long double value; } x =
2141 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
2144 my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
2145 ASSERT (strlen (result) >= 3 + 3
2146 && strisnan (result, 0, strlen (result) - 3, 0)
2147 && strcmp (result + strlen (result) - 3, " 33") == 0);
2148 ASSERT (retval == strlen (result));
2155 my_snprintf (result, sizeof (result), "%15Le %d", 1.75L, 33, 44, 55);
2156 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2157 || strcmp (result, " 1.750000e+000 33") == 0);
2158 ASSERT (retval == strlen (result));
2164 my_snprintf (result, sizeof (result), "%-15Le %d", 1.75L, 33, 44, 55);
2165 ASSERT (strcmp (result, "1.750000e+00 33") == 0
2166 || strcmp (result, "1.750000e+000 33") == 0);
2167 ASSERT (retval == strlen (result));
2170 { /* FLAG_SHOWSIGN. */
2173 my_snprintf (result, sizeof (result), "%+Le %d", 1.75L, 33, 44, 55);
2174 ASSERT (strcmp (result, "+1.750000e+00 33") == 0
2175 || strcmp (result, "+1.750000e+000 33") == 0);
2176 ASSERT (retval == strlen (result));
2182 my_snprintf (result, sizeof (result), "% Le %d", 1.75L, 33, 44, 55);
2183 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2184 || strcmp (result, " 1.750000e+000 33") == 0);
2185 ASSERT (retval == strlen (result));
2191 my_snprintf (result, sizeof (result), "%#Le %d", 1.75L, 33, 44, 55);
2192 ASSERT (strcmp (result, "1.750000e+00 33") == 0
2193 || strcmp (result, "1.750000e+000 33") == 0);
2194 ASSERT (retval == strlen (result));
2200 my_snprintf (result, sizeof (result), "%#.Le %d", 1.75L, 33, 44, 55);
2201 ASSERT (strcmp (result, "2.e+00 33") == 0
2202 || strcmp (result, "2.e+000 33") == 0);
2203 ASSERT (retval == strlen (result));
2209 my_snprintf (result, sizeof (result), "%#.Le %d", 9.75L, 33, 44, 55);
2210 ASSERT (strcmp (result, "1.e+01 33") == 0
2211 || strcmp (result, "1.e+001 33") == 0);
2212 ASSERT (retval == strlen (result));
2215 { /* FLAG_ZERO with finite number. */
2218 my_snprintf (result, sizeof (result), "%015Le %d", 1234.0L, 33, 44, 55);
2219 ASSERT (strcmp (result, "0001.234000e+03 33") == 0
2220 || strcmp (result, "001.234000e+003 33") == 0);
2221 ASSERT (retval == strlen (result));
2224 { /* FLAG_ZERO with infinite number. */
2227 my_snprintf (result, sizeof (result), "%015Le %d", -1.0L / 0.0L, 33, 44, 55);
2228 ASSERT (strcmp (result, " -inf 33") == 0
2229 || strcmp (result, " -infinity 33") == 0);
2230 ASSERT (retval == strlen (result));
2233 { /* FLAG_ZERO with NaN. */
2236 my_snprintf (result, sizeof (result), "%050Le %d", NaNl (), 33, 44, 55);
2237 ASSERT (strlen (result) == 50 + 3
2238 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2239 && strcmp (result + strlen (result) - 3, " 33") == 0);
2240 ASSERT (retval == strlen (result));
2246 my_snprintf (result, sizeof (result), "%.Le %d", 1234.0L, 33, 44, 55);
2247 ASSERT (strcmp (result, "1e+03 33") == 0
2248 || strcmp (result, "1e+003 33") == 0);
2249 ASSERT (retval == strlen (result));
2252 { /* Precision with no rounding. */
2255 my_snprintf (result, sizeof (result), "%.4Le %d", 999.951L, 33, 44, 55);
2256 ASSERT (strcmp (result, "9.9995e+02 33") == 0
2257 || strcmp (result, "9.9995e+002 33") == 0);
2258 ASSERT (retval == strlen (result));
2261 { /* Precision with rounding. */
2264 my_snprintf (result, sizeof (result), "%.4Le %d", 999.996L, 33, 44, 55);
2265 ASSERT (strcmp (result, "1.0000e+03 33") == 0
2266 || strcmp (result, "1.0000e+003 33") == 0);
2267 ASSERT (retval == strlen (result));
2270 /* Test the support of the %g format directive. */
2272 { /* A positive number. */
2275 my_snprintf (result, sizeof (result), "%g %d", 12.75, 33, 44, 55);
2276 ASSERT (strcmp (result, "12.75 33") == 0);
2277 ASSERT (retval == strlen (result));
2280 { /* A larger positive number. */
2283 my_snprintf (result, sizeof (result), "%g %d", 1234567.0, 33, 44, 55);
2284 ASSERT (strcmp (result, "1.23457e+06 33") == 0
2285 || strcmp (result, "1.23457e+006 33") == 0);
2286 ASSERT (retval == strlen (result));
2289 { /* Small and large positive numbers. */
2290 static struct { double value; const char *string; } data[] =
2292 { 1.234321234321234e-37, "1.23432e-37" },
2293 { 1.234321234321234e-36, "1.23432e-36" },
2294 { 1.234321234321234e-35, "1.23432e-35" },
2295 { 1.234321234321234e-34, "1.23432e-34" },
2296 { 1.234321234321234e-33, "1.23432e-33" },
2297 { 1.234321234321234e-32, "1.23432e-32" },
2298 { 1.234321234321234e-31, "1.23432e-31" },
2299 { 1.234321234321234e-30, "1.23432e-30" },
2300 { 1.234321234321234e-29, "1.23432e-29" },
2301 { 1.234321234321234e-28, "1.23432e-28" },
2302 { 1.234321234321234e-27, "1.23432e-27" },
2303 { 1.234321234321234e-26, "1.23432e-26" },
2304 { 1.234321234321234e-25, "1.23432e-25" },
2305 { 1.234321234321234e-24, "1.23432e-24" },
2306 { 1.234321234321234e-23, "1.23432e-23" },
2307 { 1.234321234321234e-22, "1.23432e-22" },
2308 { 1.234321234321234e-21, "1.23432e-21" },
2309 { 1.234321234321234e-20, "1.23432e-20" },
2310 { 1.234321234321234e-19, "1.23432e-19" },
2311 { 1.234321234321234e-18, "1.23432e-18" },
2312 { 1.234321234321234e-17, "1.23432e-17" },
2313 { 1.234321234321234e-16, "1.23432e-16" },
2314 { 1.234321234321234e-15, "1.23432e-15" },
2315 { 1.234321234321234e-14, "1.23432e-14" },
2316 { 1.234321234321234e-13, "1.23432e-13" },
2317 { 1.234321234321234e-12, "1.23432e-12" },
2318 { 1.234321234321234e-11, "1.23432e-11" },
2319 { 1.234321234321234e-10, "1.23432e-10" },
2320 { 1.234321234321234e-9, "1.23432e-09" },
2321 { 1.234321234321234e-8, "1.23432e-08" },
2322 { 1.234321234321234e-7, "1.23432e-07" },
2323 { 1.234321234321234e-6, "1.23432e-06" },
2324 { 1.234321234321234e-5, "1.23432e-05" },
2325 { 1.234321234321234e-4, "0.000123432" },
2326 { 1.234321234321234e-3, "0.00123432" },
2327 { 1.234321234321234e-2, "0.0123432" },
2328 { 1.234321234321234e-1, "0.123432" },
2329 { 1.234321234321234, "1.23432" },
2330 { 1.234321234321234e1, "12.3432" },
2331 { 1.234321234321234e2, "123.432" },
2332 { 1.234321234321234e3, "1234.32" },
2333 { 1.234321234321234e4, "12343.2" },
2334 { 1.234321234321234e5, "123432" },
2335 { 1.234321234321234e6, "1.23432e+06" },
2336 { 1.234321234321234e7, "1.23432e+07" },
2337 { 1.234321234321234e8, "1.23432e+08" },
2338 { 1.234321234321234e9, "1.23432e+09" },
2339 { 1.234321234321234e10, "1.23432e+10" },
2340 { 1.234321234321234e11, "1.23432e+11" },
2341 { 1.234321234321234e12, "1.23432e+12" },
2342 { 1.234321234321234e13, "1.23432e+13" },
2343 { 1.234321234321234e14, "1.23432e+14" },
2344 { 1.234321234321234e15, "1.23432e+15" },
2345 { 1.234321234321234e16, "1.23432e+16" },
2346 { 1.234321234321234e17, "1.23432e+17" },
2347 { 1.234321234321234e18, "1.23432e+18" },
2348 { 1.234321234321234e19, "1.23432e+19" },
2349 { 1.234321234321234e20, "1.23432e+20" },
2350 { 1.234321234321234e21, "1.23432e+21" },
2351 { 1.234321234321234e22, "1.23432e+22" },
2352 { 1.234321234321234e23, "1.23432e+23" },
2353 { 1.234321234321234e24, "1.23432e+24" },
2354 { 1.234321234321234e25, "1.23432e+25" },
2355 { 1.234321234321234e26, "1.23432e+26" },
2356 { 1.234321234321234e27, "1.23432e+27" },
2357 { 1.234321234321234e28, "1.23432e+28" },
2358 { 1.234321234321234e29, "1.23432e+29" },
2359 { 1.234321234321234e30, "1.23432e+30" },
2360 { 1.234321234321234e31, "1.23432e+31" },
2361 { 1.234321234321234e32, "1.23432e+32" },
2362 { 1.234321234321234e33, "1.23432e+33" },
2363 { 1.234321234321234e34, "1.23432e+34" },
2364 { 1.234321234321234e35, "1.23432e+35" },
2365 { 1.234321234321234e36, "1.23432e+36" }
2368 for (k = 0; k < SIZEOF (data); k++)
2372 my_snprintf (result, sizeof (result), "%g", data[k].value);
2373 const char *expected = data[k].string;
2374 ASSERT (strcmp (result, expected) == 0
2375 /* Some implementations produce exponents with 3 digits. */
2376 || (expected[strlen (expected) - 4] == 'e'
2377 && strlen (result) == strlen (expected) + 1
2378 && memcmp (result, expected, strlen (expected) - 2) == 0
2379 && result[strlen (expected) - 2] == '0'
2380 && strcmp (result + strlen (expected) - 1,
2381 expected + strlen (expected) - 2)
2383 ASSERT (retval == strlen (result));
2387 { /* A negative number. */
2390 my_snprintf (result, sizeof (result), "%g %d", -0.03125, 33, 44, 55);
2391 ASSERT (strcmp (result, "-0.03125 33") == 0);
2392 ASSERT (retval == strlen (result));
2395 { /* Positive zero. */
2398 my_snprintf (result, sizeof (result), "%g %d", 0.0, 33, 44, 55);
2399 ASSERT (strcmp (result, "0 33") == 0);
2400 ASSERT (retval == strlen (result));
2403 { /* Negative zero. */
2406 my_snprintf (result, sizeof (result), "%g %d", -zerod, 33, 44, 55);
2407 if (have_minus_zero ())
2408 ASSERT (strcmp (result, "-0 33") == 0);
2409 ASSERT (retval == strlen (result));
2412 { /* Positive infinity. */
2415 my_snprintf (result, sizeof (result), "%g %d", 1.0 / 0.0, 33, 44, 55);
2416 ASSERT (strcmp (result, "inf 33") == 0
2417 || strcmp (result, "infinity 33") == 0);
2418 ASSERT (retval == strlen (result));
2421 { /* Negative infinity. */
2424 my_snprintf (result, sizeof (result), "%g %d", -1.0 / 0.0, 33, 44, 55);
2425 ASSERT (strcmp (result, "-inf 33") == 0
2426 || strcmp (result, "-infinity 33") == 0);
2427 ASSERT (retval == strlen (result));
2433 my_snprintf (result, sizeof (result), "%g %d", NaNd (), 33, 44, 55);
2434 ASSERT (strlen (result) >= 3 + 3
2435 && strisnan (result, 0, strlen (result) - 3, 0)
2436 && strcmp (result + strlen (result) - 3, " 33") == 0);
2437 ASSERT (retval == strlen (result));
2443 my_snprintf (result, sizeof (result), "%10g %d", 1.75, 33, 44, 55);
2444 ASSERT (strcmp (result, " 1.75 33") == 0);
2445 ASSERT (retval == strlen (result));
2451 my_snprintf (result, sizeof (result), "%-10g %d", 1.75, 33, 44, 55);
2452 ASSERT (strcmp (result, "1.75 33") == 0);
2453 ASSERT (retval == strlen (result));
2456 { /* FLAG_SHOWSIGN. */
2459 my_snprintf (result, sizeof (result), "%+g %d", 1.75, 33, 44, 55);
2460 ASSERT (strcmp (result, "+1.75 33") == 0);
2461 ASSERT (retval == strlen (result));
2467 my_snprintf (result, sizeof (result), "% g %d", 1.75, 33, 44, 55);
2468 ASSERT (strcmp (result, " 1.75 33") == 0);
2469 ASSERT (retval == strlen (result));
2475 my_snprintf (result, sizeof (result), "%#g %d", 1.75, 33, 44, 55);
2476 ASSERT (strcmp (result, "1.75000 33") == 0);
2477 ASSERT (retval == strlen (result));
2483 my_snprintf (result, sizeof (result), "%#.g %d", 1.75, 33, 44, 55);
2484 ASSERT (strcmp (result, "2. 33") == 0);
2485 ASSERT (retval == strlen (result));
2491 my_snprintf (result, sizeof (result), "%#.g %d", 9.75, 33, 44, 55);
2492 ASSERT (strcmp (result, "1.e+01 33") == 0
2493 || strcmp (result, "1.e+001 33") == 0);
2494 ASSERT (retval == strlen (result));
2497 { /* FLAG_ZERO with finite number. */
2500 my_snprintf (result, sizeof (result), "%010g %d", 1234.0, 33, 44, 55);
2501 ASSERT (strcmp (result, "0000001234 33") == 0);
2502 ASSERT (retval == strlen (result));
2505 { /* FLAG_ZERO with infinite number. */
2508 my_snprintf (result, sizeof (result), "%015g %d", -1.0 / 0.0, 33, 44, 55);
2509 ASSERT (strcmp (result, " -inf 33") == 0
2510 || strcmp (result, " -infinity 33") == 0);
2511 ASSERT (retval == strlen (result));
2514 { /* FLAG_ZERO with NaN. */
2517 my_snprintf (result, sizeof (result), "%050g %d", NaNd (), 33, 44, 55);
2518 ASSERT (strlen (result) == 50 + 3
2519 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2520 && strcmp (result + strlen (result) - 3, " 33") == 0);
2521 ASSERT (retval == strlen (result));
2527 my_snprintf (result, sizeof (result), "%.g %d", 1234.0, 33, 44, 55);
2528 ASSERT (strcmp (result, "1e+03 33") == 0
2529 || strcmp (result, "1e+003 33") == 0);
2530 ASSERT (retval == strlen (result));
2533 { /* Precision with no rounding. */
2536 my_snprintf (result, sizeof (result), "%.5g %d", 999.951, 33, 44, 55);
2537 ASSERT (strcmp (result, "999.95 33") == 0);
2538 ASSERT (retval == strlen (result));
2541 { /* Precision with rounding. */
2544 my_snprintf (result, sizeof (result), "%.5g %d", 999.996, 33, 44, 55);
2545 ASSERT (strcmp (result, "1000 33") == 0);
2546 ASSERT (retval == strlen (result));
2549 { /* A positive number. */
2552 my_snprintf (result, sizeof (result), "%Lg %d", 12.75L, 33, 44, 55);
2553 ASSERT (strcmp (result, "12.75 33") == 0);
2554 ASSERT (retval == strlen (result));
2557 { /* A larger positive number. */
2560 my_snprintf (result, sizeof (result), "%Lg %d", 1234567.0L, 33, 44, 55);
2561 ASSERT (strcmp (result, "1.23457e+06 33") == 0
2562 || strcmp (result, "1.23457e+006 33") == 0);
2563 ASSERT (retval == strlen (result));
2566 { /* Small and large positive numbers. */
2567 static struct { long double value; const char *string; } data[] =
2569 { 1.234321234321234e-37L, "1.23432e-37" },
2570 { 1.234321234321234e-36L, "1.23432e-36" },
2571 { 1.234321234321234e-35L, "1.23432e-35" },
2572 { 1.234321234321234e-34L, "1.23432e-34" },
2573 { 1.234321234321234e-33L, "1.23432e-33" },
2574 { 1.234321234321234e-32L, "1.23432e-32" },
2575 { 1.234321234321234e-31L, "1.23432e-31" },
2576 { 1.234321234321234e-30L, "1.23432e-30" },
2577 { 1.234321234321234e-29L, "1.23432e-29" },
2578 { 1.234321234321234e-28L, "1.23432e-28" },
2579 { 1.234321234321234e-27L, "1.23432e-27" },
2580 { 1.234321234321234e-26L, "1.23432e-26" },
2581 { 1.234321234321234e-25L, "1.23432e-25" },
2582 { 1.234321234321234e-24L, "1.23432e-24" },
2583 { 1.234321234321234e-23L, "1.23432e-23" },
2584 { 1.234321234321234e-22L, "1.23432e-22" },
2585 { 1.234321234321234e-21L, "1.23432e-21" },
2586 { 1.234321234321234e-20L, "1.23432e-20" },
2587 { 1.234321234321234e-19L, "1.23432e-19" },
2588 { 1.234321234321234e-18L, "1.23432e-18" },
2589 { 1.234321234321234e-17L, "1.23432e-17" },
2590 { 1.234321234321234e-16L, "1.23432e-16" },
2591 { 1.234321234321234e-15L, "1.23432e-15" },
2592 { 1.234321234321234e-14L, "1.23432e-14" },
2593 { 1.234321234321234e-13L, "1.23432e-13" },
2594 { 1.234321234321234e-12L, "1.23432e-12" },
2595 { 1.234321234321234e-11L, "1.23432e-11" },
2596 { 1.234321234321234e-10L, "1.23432e-10" },
2597 { 1.234321234321234e-9L, "1.23432e-09" },
2598 { 1.234321234321234e-8L, "1.23432e-08" },
2599 { 1.234321234321234e-7L, "1.23432e-07" },
2600 { 1.234321234321234e-6L, "1.23432e-06" },
2601 { 1.234321234321234e-5L, "1.23432e-05" },
2602 { 1.234321234321234e-4L, "0.000123432" },
2603 { 1.234321234321234e-3L, "0.00123432" },
2604 { 1.234321234321234e-2L, "0.0123432" },
2605 { 1.234321234321234e-1L, "0.123432" },
2606 { 1.234321234321234L, "1.23432" },
2607 { 1.234321234321234e1L, "12.3432" },
2608 { 1.234321234321234e2L, "123.432" },
2609 { 1.234321234321234e3L, "1234.32" },
2610 { 1.234321234321234e4L, "12343.2" },
2611 { 1.234321234321234e5L, "123432" },
2612 { 1.234321234321234e6L, "1.23432e+06" },
2613 { 1.234321234321234e7L, "1.23432e+07" },
2614 { 1.234321234321234e8L, "1.23432e+08" },
2615 { 1.234321234321234e9L, "1.23432e+09" },
2616 { 1.234321234321234e10L, "1.23432e+10" },
2617 { 1.234321234321234e11L, "1.23432e+11" },
2618 { 1.234321234321234e12L, "1.23432e+12" },
2619 { 1.234321234321234e13L, "1.23432e+13" },
2620 { 1.234321234321234e14L, "1.23432e+14" },
2621 { 1.234321234321234e15L, "1.23432e+15" },
2622 { 1.234321234321234e16L, "1.23432e+16" },
2623 { 1.234321234321234e17L, "1.23432e+17" },
2624 { 1.234321234321234e18L, "1.23432e+18" },
2625 { 1.234321234321234e19L, "1.23432e+19" },
2626 { 1.234321234321234e20L, "1.23432e+20" },
2627 { 1.234321234321234e21L, "1.23432e+21" },
2628 { 1.234321234321234e22L, "1.23432e+22" },
2629 { 1.234321234321234e23L, "1.23432e+23" },
2630 { 1.234321234321234e24L, "1.23432e+24" },
2631 { 1.234321234321234e25L, "1.23432e+25" },
2632 { 1.234321234321234e26L, "1.23432e+26" },
2633 { 1.234321234321234e27L, "1.23432e+27" },
2634 { 1.234321234321234e28L, "1.23432e+28" },
2635 { 1.234321234321234e29L, "1.23432e+29" },
2636 { 1.234321234321234e30L, "1.23432e+30" },
2637 { 1.234321234321234e31L, "1.23432e+31" },
2638 { 1.234321234321234e32L, "1.23432e+32" },
2639 { 1.234321234321234e33L, "1.23432e+33" },
2640 { 1.234321234321234e34L, "1.23432e+34" },
2641 { 1.234321234321234e35L, "1.23432e+35" },
2642 { 1.234321234321234e36L, "1.23432e+36" }
2645 for (k = 0; k < SIZEOF (data); k++)
2649 my_snprintf (result, sizeof (result), "%Lg", data[k].value);
2650 const char *expected = data[k].string;
2651 ASSERT (strcmp (result, expected) == 0
2652 /* Some implementations produce exponents with 3 digits. */
2653 || (expected[strlen (expected) - 4] == 'e'
2654 && strlen (result) == strlen (expected) + 1
2655 && memcmp (result, expected, strlen (expected) - 2) == 0
2656 && result[strlen (expected) - 2] == '0'
2657 && strcmp (result + strlen (expected) - 1,
2658 expected + strlen (expected) - 2)
2660 ASSERT (retval == strlen (result));
2664 { /* A negative number. */
2667 my_snprintf (result, sizeof (result), "%Lg %d", -0.03125L, 33, 44, 55);
2668 ASSERT (strcmp (result, "-0.03125 33") == 0);
2669 ASSERT (retval == strlen (result));
2672 { /* Positive zero. */
2675 my_snprintf (result, sizeof (result), "%Lg %d", 0.0L, 33, 44, 55);
2676 ASSERT (strcmp (result, "0 33") == 0);
2677 ASSERT (retval == strlen (result));
2680 { /* Negative zero. */
2683 my_snprintf (result, sizeof (result), "%Lg %d", minus_zerol, 33, 44, 55);
2684 if (have_minus_zero ())
2685 ASSERT (strcmp (result, "-0 33") == 0);
2686 ASSERT (retval == strlen (result));
2689 { /* Positive infinity. */
2692 my_snprintf (result, sizeof (result), "%Lg %d", 1.0L / 0.0L, 33, 44, 55);
2693 ASSERT (strcmp (result, "inf 33") == 0
2694 || strcmp (result, "infinity 33") == 0);
2695 ASSERT (retval == strlen (result));
2698 { /* Negative infinity. */
2701 my_snprintf (result, sizeof (result), "%Lg %d", -1.0L / 0.0L, 33, 44, 55);
2702 ASSERT (strcmp (result, "-inf 33") == 0
2703 || strcmp (result, "-infinity 33") == 0);
2704 ASSERT (retval == strlen (result));
2710 my_snprintf (result, sizeof (result), "%Lg %d", NaNl (), 33, 44, 55);
2711 ASSERT (strlen (result) >= 3 + 3
2712 && strisnan (result, 0, strlen (result) - 3, 0)
2713 && strcmp (result + strlen (result) - 3, " 33") == 0);
2714 ASSERT (retval == strlen (result));
2716 #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_))
2718 static union { unsigned int word[4]; long double value; } x =
2719 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
2722 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2723 ASSERT (strlen (result) >= 3 + 3
2724 && strisnan (result, 0, strlen (result) - 3, 0)
2725 && strcmp (result + strlen (result) - 3, " 33") == 0);
2726 ASSERT (retval == strlen (result));
2729 /* Signalling NaN. */
2730 static union { unsigned int word[4]; long double value; } x =
2731 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
2734 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2735 ASSERT (strlen (result) >= 3 + 3
2736 && strisnan (result, 0, strlen (result) - 3, 0)
2737 && strcmp (result + strlen (result) - 3, " 33") == 0);
2738 ASSERT (retval == strlen (result));
2740 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
2741 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
2742 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
2743 Application Architecture.
2744 Table 5-2 "Floating-Point Register Encodings"
2745 Figure 5-6 "Memory to Floating-Point Register Data Translation"
2748 static union { unsigned int word[4]; long double value; } x =
2749 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
2752 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2753 ASSERT (strlen (result) >= 3 + 3
2754 && strisnan (result, 0, strlen (result) - 3, 0)
2755 && strcmp (result + strlen (result) - 3, " 33") == 0);
2756 ASSERT (retval == strlen (result));
2758 { /* Pseudo-Infinity. */
2759 static union { unsigned int word[4]; long double value; } x =
2760 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
2763 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2764 ASSERT (strlen (result) >= 3 + 3
2765 && strisnan (result, 0, strlen (result) - 3, 0)
2766 && strcmp (result + strlen (result) - 3, " 33") == 0);
2767 ASSERT (retval == strlen (result));
2769 { /* Pseudo-Zero. */
2770 static union { unsigned int word[4]; long double value; } x =
2771 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
2774 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2775 ASSERT (strlen (result) >= 3 + 3
2776 && strisnan (result, 0, strlen (result) - 3, 0)
2777 && strcmp (result + strlen (result) - 3, " 33") == 0);
2778 ASSERT (retval == strlen (result));
2780 { /* Unnormalized number. */
2781 static union { unsigned int word[4]; long double value; } x =
2782 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
2785 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2786 ASSERT (strlen (result) >= 3 + 3
2787 && strisnan (result, 0, strlen (result) - 3, 0)
2788 && strcmp (result + strlen (result) - 3, " 33") == 0);
2789 ASSERT (retval == strlen (result));
2791 { /* Pseudo-Denormal. */
2792 static union { unsigned int word[4]; long double value; } x =
2793 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
2796 my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
2797 ASSERT (strlen (result) >= 3 + 3
2798 && strisnan (result, 0, strlen (result) - 3, 0)
2799 && strcmp (result + strlen (result) - 3, " 33") == 0);
2800 ASSERT (retval == strlen (result));
2807 my_snprintf (result, sizeof (result), "%10Lg %d", 1.75L, 33, 44, 55);
2808 ASSERT (strcmp (result, " 1.75 33") == 0);
2809 ASSERT (retval == strlen (result));
2815 my_snprintf (result, sizeof (result), "%-10Lg %d", 1.75L, 33, 44, 55);
2816 ASSERT (strcmp (result, "1.75 33") == 0);
2817 ASSERT (retval == strlen (result));
2820 { /* FLAG_SHOWSIGN. */
2823 my_snprintf (result, sizeof (result), "%+Lg %d", 1.75L, 33, 44, 55);
2824 ASSERT (strcmp (result, "+1.75 33") == 0);
2825 ASSERT (retval == strlen (result));
2831 my_snprintf (result, sizeof (result), "% Lg %d", 1.75L, 33, 44, 55);
2832 ASSERT (strcmp (result, " 1.75 33") == 0);
2833 ASSERT (retval == strlen (result));
2839 my_snprintf (result, sizeof (result), "%#Lg %d", 1.75L, 33, 44, 55);
2840 ASSERT (strcmp (result, "1.75000 33") == 0);
2841 ASSERT (retval == strlen (result));
2847 my_snprintf (result, sizeof (result), "%#.Lg %d", 1.75L, 33, 44, 55);
2848 ASSERT (strcmp (result, "2. 33") == 0);
2849 ASSERT (retval == strlen (result));
2855 my_snprintf (result, sizeof (result), "%#.Lg %d", 9.75L, 33, 44, 55);
2856 ASSERT (strcmp (result, "1.e+01 33") == 0
2857 || strcmp (result, "1.e+001 33") == 0);
2858 ASSERT (retval == strlen (result));
2861 { /* FLAG_ZERO with finite number. */
2864 my_snprintf (result, sizeof (result), "%010Lg %d", 1234.0L, 33, 44, 55);
2865 ASSERT (strcmp (result, "0000001234 33") == 0);
2866 ASSERT (retval == strlen (result));
2869 { /* FLAG_ZERO with infinite number. */
2872 my_snprintf (result, sizeof (result), "%015Lg %d", -1.0L / 0.0L, 33, 44, 55);
2873 ASSERT (strcmp (result, " -inf 33") == 0
2874 || strcmp (result, " -infinity 33") == 0);
2875 ASSERT (retval == strlen (result));
2878 { /* FLAG_ZERO with NaN. */
2881 my_snprintf (result, sizeof (result), "%050Lg %d", NaNl (), 33, 44, 55);
2882 ASSERT (strlen (result) == 50 + 3
2883 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2884 && strcmp (result + strlen (result) - 3, " 33") == 0);
2885 ASSERT (retval == strlen (result));
2891 my_snprintf (result, sizeof (result), "%.Lg %d", 1234.0L, 33, 44, 55);
2892 ASSERT (strcmp (result, "1e+03 33") == 0
2893 || strcmp (result, "1e+003 33") == 0);
2894 ASSERT (retval == strlen (result));
2897 { /* Precision with no rounding. */
2900 my_snprintf (result, sizeof (result), "%.5Lg %d", 999.951L, 33, 44, 55);
2901 ASSERT (strcmp (result, "999.95 33") == 0);
2902 ASSERT (retval == strlen (result));
2905 { /* Precision with rounding. */
2908 my_snprintf (result, sizeof (result), "%.5Lg %d", 999.996L, 33, 44, 55);
2909 ASSERT (strcmp (result, "1000 33") == 0);
2910 ASSERT (retval == strlen (result));
2913 /* Test the support of the %n format directive. */
2919 my_snprintf (result, sizeof (result), "%d %n", 123, &count, 33, 44, 55);
2920 ASSERT (strcmp (result, "123 ") == 0);
2921 ASSERT (retval == strlen (result));
2922 ASSERT (count == 4);
2925 /* Test the support of the POSIX/XSI format strings with positions. */
2930 my_snprintf (result, sizeof (result), "%2$d %1$d", 33, 55);
2931 ASSERT (strcmp (result, "55 33") == 0);
2932 ASSERT (retval == strlen (result));
2935 /* Test the support of the grouping flag. */
2940 my_snprintf (result, sizeof (result), "%'d %d", 1234567, 99);
2941 ASSERT (result[strlen (result) - 1] == '9');
2942 ASSERT (retval == strlen (result));
2945 /* Test the support of the left-adjust flag. */
2950 my_snprintf (result, sizeof (result), "a%*sc", -3, "b");
2951 ASSERT (strcmp (result, "ab c") == 0);
2952 ASSERT (retval == strlen (result));
2958 my_snprintf (result, sizeof (result), "a%-*sc", 3, "b");
2959 ASSERT (strcmp (result, "ab c") == 0);
2960 ASSERT (retval == strlen (result));
2966 my_snprintf (result, sizeof (result), "a%-*sc", -3, "b");
2967 ASSERT (strcmp (result, "ab c") == 0);
2968 ASSERT (retval == strlen (result));
2971 /* Test the support of large precision. */
2976 my_snprintf (result, sizeof (result), "%.4000d %d", 1234567, 99);
2978 for (i = 0; i < 4000 - 7; i++)
2979 ASSERT (result[i] == '0');
2980 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
2981 ASSERT (retval == strlen (result));
2987 my_snprintf (result, sizeof (result), "%.*d %d", 4000, 1234567, 99);
2989 for (i = 0; i < 4000 - 7; i++)
2990 ASSERT (result[i] == '0');
2991 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
2992 ASSERT (retval == strlen (result));
2998 my_snprintf (result, sizeof (result), "%.4000d %d", -1234567, 99);
3000 ASSERT (result[0] == '-');
3001 for (i = 0; i < 4000 - 7; i++)
3002 ASSERT (result[1 + i] == '0');
3003 ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
3004 ASSERT (retval == strlen (result));
3010 my_snprintf (result, sizeof (result), "%.4000u %d", 1234567, 99);
3012 for (i = 0; i < 4000 - 7; i++)
3013 ASSERT (result[i] == '0');
3014 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3015 ASSERT (retval == strlen (result));
3021 my_snprintf (result, sizeof (result), "%.4000o %d", 1234567, 99);
3023 for (i = 0; i < 4000 - 7; i++)
3024 ASSERT (result[i] == '0');
3025 ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
3026 ASSERT (retval == strlen (result));
3032 my_snprintf (result, sizeof (result), "%.4000x %d", 1234567, 99);
3034 for (i = 0; i < 4000 - 6; i++)
3035 ASSERT (result[i] == '0');
3036 ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
3037 ASSERT (retval == strlen (result));
3043 my_snprintf (result, sizeof (result), "%#.4000x %d", 1234567, 99);
3045 ASSERT (result[0] == '0');
3046 ASSERT (result[1] == 'x');
3047 for (i = 0; i < 4000 - 6; i++)
3048 ASSERT (result[2 + i] == '0');
3049 ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
3050 ASSERT (retval == strlen (result));
3059 for (i = 0; i < sizeof (input) - 1; i++)
3060 input[i] = 'a' + ((1000000 / (i + 1)) % 26);
3062 retval = my_snprintf (result, sizeof (result), "%.4000s %d", input, 99);
3063 ASSERT (memcmp (result, input, 4000) == 0);
3064 ASSERT (strcmp (result + 4000, " 99") == 0);
3065 ASSERT (retval == strlen (result));
3068 /* Test the support of the %s format directive. */
3070 /* To verify that these tests succeed, it is necessary to run them under
3071 a tool that checks against invalid memory accesses, such as ElectricFence
3072 or "valgrind --tool=memcheck". */
3076 for (i = 1; i <= 8; i++)
3082 block = (char *) malloc (i);
3083 memcpy (block, "abcdefgh", i);
3084 retval = my_snprintf (result, sizeof (result), "%.*s", (int) i, block);
3085 ASSERT (memcmp (result, block, i) == 0);
3086 ASSERT (result[i] == '\0');
3087 ASSERT (retval == strlen (result));
3095 for (i = 1; i <= 8; i++)
3102 block = (wchar_t *) malloc (i * sizeof (wchar_t));
3103 for (j = 0; j < i; j++)
3104 block[j] = "abcdefgh"[j];
3105 retval = my_snprintf (result, sizeof (result), "%.*ls", (int) i, block);
3106 ASSERT (memcmp (result, "abcdefgh", i) == 0);
3107 ASSERT (result[i] == '\0');
3108 ASSERT (retval == strlen (result));