Module Name:    src
Committed By:   riastradh
Date:           Thu May  2 00:01:48 UTC 2024

Modified Files:
        src/tests/lib/libm: t_fe_round.c

Log Message:
tests/lib/libm/t_fe_round: Test nearbyintl.

This uses inputs that can't be distinguished with only 53 bits of
precision, so it should work in essentially all long double formats
to detect when nearbyintl is incorrectly implemented in terms of
nearbyint.

PR lib/58054


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/tests/lib/libm/t_fe_round.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/libm/t_fe_round.c
diff -u src/tests/lib/libm/t_fe_round.c:1.10 src/tests/lib/libm/t_fe_round.c:1.11
--- src/tests/lib/libm/t_fe_round.c:1.10	Thu May  2 00:00:47 2024
+++ src/tests/lib/libm/t_fe_round.c	Thu May  2 00:01:48 2024
@@ -143,6 +143,61 @@ ATF_TC_BODY(fe_nearbyint, tc)
 	}
 }
 
+#ifdef __HAVE_LONG_DOUBLE
+
+/*
+ * Use one bit more than fits in IEEE 754 binary64.
+ */
+static const struct {
+	int round_mode;
+	long double input;
+	long int expected;
+} valuesl[] = {
+	{ FE_TOWARDZERO,	0x2.00000000000008p+52L, 0x20000000000000 },
+	{ FE_DOWNWARD,		0x2.00000000000008p+52L, 0x20000000000000 },
+	{ FE_UPWARD,		0x2.00000000000008p+52L, 0x20000000000001 },
+	{ FE_TONEAREST,		0x2.00000000000008p+52L, 0x20000000000000 },
+	{ FE_TOWARDZERO,	0x2.00000000000018p+52L, 0x20000000000001 },
+	{ FE_DOWNWARD,		0x2.00000000000018p+52L, 0x20000000000001 },
+	{ FE_UPWARD,		0x2.00000000000018p+52L, 0x20000000000002 },
+	{ FE_TONEAREST,		0x2.00000000000018p+52L, 0x20000000000002 },
+};
+
+ATF_TC(fe_nearbyintl);
+ATF_TC_HEAD(fe_nearbyintl, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Checking IEEE 754 rounding modes using nearbyintl");
+}
+
+ATF_TC_BODY(fe_nearbyintl, tc)
+{
+	long double received, ipart, fpart;
+
+	for (unsigned int i = 0; i < __arraycount(valuesl); i++) {
+		fesetround(valuesl[i].round_mode);
+
+		received = nearbyintl(valuesl[i].input);
+		fpart = modfl(received, &ipart);
+		ATF_CHECK_MSG(fpart == 0,
+		    "%s nearbyintl(%Lf) has fractional part %Lf",
+		    rmname(values[i].round_mode), valuesl[i].input, fpart);
+		ATF_CHECK_MSG((long int)received == valuesl[i].expected,
+		    "%s [%u] nearbyint(%Lf): got %Lf, expected %ld",
+		    rmname(values[i].round_mode), i,
+		    valuesl[i].input, received, valuesl[i].expected);
+
+		/* Do we get the same rounding mode out? */
+		ATF_CHECK_MSG(fegetround() == valuesl[i].round_mode,
+		    "[%u] set %d (%s), got %d (%s)",
+		    i,
+		    valuesl[i].round_mode, rmname(valuesl[i].round_mode),
+		    fegetround(), rmname(fegetround()));
+	}
+}
+
+#endif
+
 static const struct {
 	double input;
 	double toward;
@@ -209,6 +264,9 @@ ATF_TP_ADD_TCS(tp)
 
 	ATF_TP_ADD_TC(tp, fe_round);
 	ATF_TP_ADD_TC(tp, fe_nearbyint);
+#ifdef __HAVE_LONG_DOUBLE
+	ATF_TP_ADD_TC(tp, fe_nearbyintl);
+#endif
 	ATF_TP_ADD_TC(tp, fe_nextafter);
 	ATF_TP_ADD_TC(tp, fe_nexttoward);
 

Reply via email to