Thu May 2 00:00:47 2024 UTC (18d)
tests/lib/libm/t_fe_round: Tidy up nearbyint test.

Prompted by PR lib/58054.


(riastradh)
diff -r1.9 -r1.10 src/tests/lib/libm/t_fe_round.c

cvs diff -r1.9 -r1.10 src/tests/lib/libm/t_fe_round.c (expand / switch to unified diff)

--- src/tests/lib/libm/t_fe_round.c 2017/08/21 17:11:18 1.9
+++ src/tests/lib/libm/t_fe_round.c 2024/05/02 00:00:47 1.10
@@ -8,26 +8,43 @@ @@ -8,26 +8,43 @@
8#include <atf-c.h> 8#include <atf-c.h>
9#include <fenv.h> 9#include <fenv.h>
10#ifdef __HAVE_FENV 10#ifdef __HAVE_FENV
11#include <math.h> 11#include <math.h>
12#include <stdio.h> 12#include <stdio.h>
13#include <stdlib.h> 13#include <stdlib.h>
14 14
15/*#pragma STDC FENV_ACCESS ON gcc?? */ 15/*#pragma STDC FENV_ACCESS ON gcc?? */
16 16
17#define INT 9223L 17#define INT 9223L
18 18
19#define EPSILON 0.001 19#define EPSILON 0.001
20 20
 21static const char *
 22rmname(int rm)
 23{
 24 switch (rm) {
 25 case FE_TOWARDZERO:
 26 return "FE_TOWARDZERO";
 27 case FE_DOWNWARD:
 28 return "FE_DOWNWARD";
 29 case FE_UPWARD:
 30 return "FE_UPWARD";
 31 case FE_TONEAREST:
 32 return "FE_TONEAREST";
 33 default:
 34 return "unknown";
 35 }
 36}
 37
21static const struct { 38static const struct {
22 int round_mode; 39 int round_mode;
23 double input; 40 double input;
24 long int expected; 41 long int expected;
25} values[] = { 42} values[] = {
26 { FE_DOWNWARD, 3.7, 3}, 43 { FE_DOWNWARD, 3.7, 3},
27 { FE_DOWNWARD, -3.7, -4}, 44 { FE_DOWNWARD, -3.7, -4},
28 { FE_DOWNWARD, +0, 0}, 45 { FE_DOWNWARD, +0, 0},
29 { FE_DOWNWARD, -INT-0.01, -INT-1}, 46 { FE_DOWNWARD, -INT-0.01, -INT-1},
30 { FE_DOWNWARD, +INT-0.01, INT-1}, 47 { FE_DOWNWARD, +INT-0.01, INT-1},
31 { FE_DOWNWARD, -INT+0.01, -INT}, 48 { FE_DOWNWARD, -INT+0.01, -INT},
32 { FE_DOWNWARD, +INT+0.01, INT}, 49 { FE_DOWNWARD, +INT+0.01, INT},
33#if 0 /* cpu bugs? */ 50#if 0 /* cpu bugs? */
@@ -86,49 +103,53 @@ ATF_TC_BODY(fe_round, tc) @@ -86,49 +103,53 @@ ATF_TC_BODY(fe_round, tc)
86 103
87 /* Do we get the same rounding mode out? */ 104 /* Do we get the same rounding mode out? */
88 ATF_CHECK_MSG( 105 ATF_CHECK_MSG(
89 (fegetround() == values[i].round_mode), 106 (fegetround() == values[i].round_mode),
90 "Didn't get the same rounding mode out!\n" 107 "Didn't get the same rounding mode out!\n"
91 "(index %d) fed in %d rounding mode, got %d out\n", 108 "(index %d) fed in %d rounding mode, got %d out\n",
92 i, values[i].round_mode, fegetround()); 109 i, values[i].round_mode, fegetround());
93 } 110 }
94} 111}
95 112
96ATF_TC(fe_nearbyint); 113ATF_TC(fe_nearbyint);
97ATF_TC_HEAD(fe_nearbyint, tc) 114ATF_TC_HEAD(fe_nearbyint, tc)
98{ 115{
99 atf_tc_set_md_var(tc, "descr","Checking IEEE 754 rounding modes using nearbyint"); 116 atf_tc_set_md_var(tc, "descr",
 117 "Checking IEEE 754 rounding modes using nearbyint");
100} 118}
101 119
102ATF_TC_BODY(fe_nearbyint, tc) 120ATF_TC_BODY(fe_nearbyint, tc)
103{ 121{
104 double received; 122 double received, ipart, fpart;
105 123
106 for (unsigned int i = 0; i < __arraycount(values); i++) { 124 for (unsigned int i = 0; i < __arraycount(values); i++) {
107 fesetround(values[i].round_mode); 125 fesetround(values[i].round_mode);
108 126
109 received = nearbyint(values[i].input); 127 received = nearbyint(values[i].input);
110 ATF_CHECK_MSG( 128 fpart = modf(received, &ipart);
111 (fabs(received - values[i].expected) < EPSILON), 129 ATF_CHECK_MSG(fpart == 0,
112 "nearbyint rounding wrong, difference too large\n" 130 "%s nearbyint(%f) has fractional part %f",
113 "input: %f (index %d): got %f, expected %ld\n", 131 rmname(values[i].round_mode), values[i].input, fpart);
114 values[i].input, i, received, values[i].expected); 132 ATF_CHECK_MSG((long int)received == values[i].expected,
 133 "%s [%u] nearbyint(%f) got %f, expected %ld\n",
 134 rmname(values[i].round_mode),
 135 i, values[i].input, received, values[i].expected);
115 136
116 /* Do we get the same rounding mode out? */ 137 /* Do we get the same rounding mode out? */
117 ATF_CHECK_MSG( 138 ATF_CHECK_MSG(fegetround() == values[i].round_mode,
118 (fegetround() == values[i].round_mode), 139 "[%u] set %d (%s), got %d (%s)",
119 "Didn't get the same rounding mode out!\n" 140 i,
120 "(index %d) fed in %d rounding mode, got %d out\n", 141 values[i].round_mode, rmname(values[i].round_mode),
121 i, values[i].round_mode, fegetround()); 142 fegetround(), rmname(fegetround()));
122 } 143 }
123} 144}
124 145
125static const struct { 146static const struct {
126 double input; 147 double input;
127 double toward; 148 double toward;
128 double expected; 149 double expected;
129} values2[] = { 150} values2[] = {
130 { 10.0, 11.0, 10.0 }, 151 { 10.0, 11.0, 10.0 },
131 { -5.0, -6.0, -5.0 }, 152 { -5.0, -6.0, -5.0 },
132}; 153};
133 154
134ATF_TC(fe_nextafter); 155ATF_TC(fe_nextafter);