Module Name:    src
Committed By:   martin
Date:           Thu Aug 22 19:53:56 UTC 2024

Modified Files:
        src/tests/lib/libc/stdio [netbsd-9]: t_printf.c

Log Message:
Pull up following revision(s) (requested by riastradh in ticket #1866):

        tests/lib/libc/stdio/t_printf.c: revision 1.17
        tests/lib/libc/stdio/t_printf.c: revision 1.18
        tests/lib/libc/stdio/t_printf.c: revision 1.11
        tests/lib/libc/stdio/t_printf.c: revision 1.12
        tests/lib/libc/stdio/t_printf.c: revision 1.13
        tests/lib/libc/stdio/t_printf.c: revision 1.14
        tests/lib/libc/stdio/t_printf.c: revision 1.15
        tests/lib/libc/stdio/t_printf.c: revision 1.16
        (all via patch)

tests/lib/libc/stdio/t_printf: Add a couple simple %La tests.

PR lib/56937: printf(3) long double %a formatting is broken
tests/lib/libc/stdio/t_printf: Fix %La test.
0xa.99ap+0 is closer to (long double)10.6 in x86 ld80 and in
binary128 (and possibly more formats, haven't verified).
tests/lib/libc/stdio/t_printf: Fix %a test the same way.
tests/lib/libc/stdio/t_printf: Add another %La test.

This one was adapted from the screw case shown in
https://mail-index.netbsd.org/tech-userlevel/2020/04/11/msg012329.html
which wasn't broken in our libc, but which nevertheless prompted us
to commit a wrong and apparently untested patch that has rendered
printf %La broken for the last four years, which is a little
embarrassing.  (The part of that patch that led to a buffer overrun
has been worked around, so now the output is just incorrect.)

PR lib/56937: printf(3) long double %a formatting is broken
tests/lib/libc/stdio/t_printf: Fix another rounding error.
Noted by kre.

This doesn't break a passing test or fix a failed test, at least on
x86 -- our printf produces `0x1.533p+3' for the double case and
`0xa.99ap+0' for the long double case.  But of the hexadecimal number
literals that that start with 0x5 having three hexadigits to the
right of the fractional point, 0x5.4cdp+1 closest to the IEEE 754
binary64, VAX D, x86 extended precision, and IEEE 754 binary128
floating-point numbers closest to 10.6.

The reason is that the number 10.6 (or the nearest floating-point
number in any format with enough precision) is:
101.0100 1100 1100|1100... * 2^1 = 0x5.4cc|c...p+1

If we round at the vertical bar to the _nearest_ output with three
hexadigits of precision, the result is:
101.0100 1100 1101 * 2^1 = 0x5.4cdp+1

tests/lib/libc/stdio/t_printf: Fix typo in ld128 case.
printf %La does not write the `L' suffix.

tests/lib/libc/stdio/t_printf: Fix sign error in ld128 case.
Also link back to where the test case came from.


To generate a diff of this commit:
cvs rdiff -u -r1.8.34.1 -r1.8.34.2 src/tests/lib/libc/stdio/t_printf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/lib/libc/stdio/t_printf.c
diff -u src/tests/lib/libc/stdio/t_printf.c:1.8.34.1 src/tests/lib/libc/stdio/t_printf.c:1.8.34.2
--- src/tests/lib/libc/stdio/t_printf.c:1.8.34.1	Thu Aug 22 19:40:50 2024
+++ src/tests/lib/libc/stdio/t_printf.c	Thu Aug 22 19:53:56 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: t_printf.c,v 1.8.34.1 2024/08/22 19:40:50 martin Exp $ */
+/* $NetBSD: t_printf.c,v 1.8.34.2 2024/08/22 19:53:56 martin Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -28,14 +28,16 @@
 
 #include <sys/types.h>
 #include <sys/resource.h>
+
 #include <atf-c.h>
+#include <errno.h>
+#include <float.h>
 #include <math.h>
-#include <stdio.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <time.h>
-#include <stdlib.h>
-#include <errno.h>
 
 ATF_TC(snprintf_c99);
 ATF_TC_HEAD(snprintf_c99, tc)
@@ -191,7 +193,68 @@ ATF_TC_BODY(snprintf_double_a, tc)
 	char buf[1000];
 
 	snprintf(buf, sizeof buf, "%.3a", (double)10.6);
-	ATF_REQUIRE_STREQ("0x1.533p+3", buf);
+	ATF_CHECK_MSG((strcmp(buf, "0x1.533p+3") == 0 ||
+		strcmp(buf, "0x2.a66p+2") == 0 ||
+		strcmp(buf, "0x5.4cdp+1") == 0 ||
+		strcmp(buf, "0xa.99ap+0") == 0),
+	    "buf=%s", buf);
+
+	snprintf(buf, sizeof buf, "%a", (double)0.125);
+	ATF_CHECK_MSG((strcmp(buf, "0x1p-3") == 0 ||
+		strcmp(buf, "0x2p-4") == 0 ||
+		strcmp(buf, "0x4p-5") == 0 ||
+		strcmp(buf, "0x8p-6") == 0),
+	    "buf=%s", buf);
+}
+
+ATF_TC(snprintf_long_double_a);
+ATF_TC_HEAD(snprintf_long_double_a, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test printf La format");
+}
+
+ATF_TC_BODY(snprintf_long_double_a, tc)
+{
+	char buf[1000];
+
+	snprintf(buf, sizeof buf, "%.3La", 10.6L);
+	ATF_CHECK_MSG((strcmp(buf, "0x1.533p+3") == 0 ||
+		strcmp(buf, "0x2.a66p+2") == 0 ||
+		strcmp(buf, "0x5.4cdp+1") == 0 ||
+		strcmp(buf, "0xa.99ap+0") == 0),
+	    "buf=%s", buf);
+
+	snprintf(buf, sizeof buf, "%La", 0.125L);
+	ATF_CHECK_MSG((strcmp(buf, "0x1p-3") == 0 ||
+		strcmp(buf, "0x2p-4") == 0 ||
+		strcmp(buf, "0x4p-5") == 0 ||
+		strcmp(buf, "0x8p-6") == 0),
+	    "buf=%s", buf);
+
+	/*
+	 * Test case adapted from:
+	 *
+	 * https://mail-index.netbsd.org/tech-userlevel/2020/04/11/msg012329.html
+	 */
+#if LDBL_MAX_EXP >= 16384 && LDBL_MANT_DIG >= 64
+	snprintf(buf, sizeof buf, "%La", -0xc.ecececececececep+3788L);
+	ATF_CHECK_MSG((strcmp(buf, "-0x1.9d9d9d9d9d9d9d9cp+3791") == 0 ||
+		strcmp(buf, "-0x3.3b3b3b3b3b3b3b38p+3790") == 0 ||
+		strcmp(buf, "-0x6.7676767676767674p+3789") == 0 ||
+		strcmp(buf, "-0xc.ecececececececep+3788") == 0),
+	    "buf=%s", buf);
+#endif
+
+#if LDBL_MAX_EXP >= 16384 && LDBL_MANT_DIG >= 113
+	snprintf(buf, sizeof buf, "%La",
+	    -0x1.cecececececececececececececep+3791L);
+	ATF_CHECK_MSG((strcmp(buf,
+		    "-0x1.cecececececececececececececep+3791") == 0 ||
+		strcmp(buf, "-0x3.3333333333333338p+3790") == 0 ||
+		strcmp(buf, "-0x6.767676767676767p+3789") == 0 ||
+		strcmp(buf, "-0xc.ecececececececep+3788") == 0),
+	    "buf=%s", buf);
+#endif
 }
 
 /* is "long double" and "double" different? */
@@ -235,6 +298,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, snprintf_float);
 	ATF_TP_ADD_TC(tp, sprintf_zeropad);
 	ATF_TP_ADD_TC(tp, snprintf_double_a);
+	ATF_TP_ADD_TC(tp, snprintf_long_double_a);
 #ifndef WIDE_DOUBLE
 	ATF_TP_ADD_TC(tp, pr57250_fix);
 #endif

Reply via email to