1//===-- Utility class to test fmod special numbers ------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H
10#define LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H
11
12#include "src/__support/FPUtil/BasicOperations.h"
13#include "src/__support/FPUtil/NearestIntegerOperations.h"
14#include "test/UnitTest/FEnvSafeTest.h"
15#include "test/UnitTest/FPMatcher.h"
16#include "test/UnitTest/Test.h"
17
18#include "hdr/math_macros.h"
19
20#define TEST_SPECIAL(x, y, expected, dom_err, expected_exception) \
21 EXPECT_FP_EQ(expected, f(x, y)); \
22 EXPECT_MATH_ERRNO((dom_err) ? EDOM : 0); \
23 EXPECT_FP_EXCEPTION(expected_exception); \
24 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT)
25
26#define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, false, 0)
27
28template <typename T>
29class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
30
31 DECLARE_SPECIAL_CONSTANTS(T)
32
33public:
34 typedef T (*FModFunc)(T, T);
35
36 void testSpecialNumbers(FModFunc f) {
37 // fmod (+0, y) == +0 for y != 0.
38 TEST_SPECIAL(0.0, 3.0, 0.0, false, 0);
39 TEST_SPECIAL(0.0, min_denormal, 0.0, false, 0);
40 TEST_SPECIAL(0.0, -min_denormal, 0.0, false, 0);
41 TEST_SPECIAL(0.0, min_normal, 0.0, false, 0);
42 TEST_SPECIAL(0.0, -min_normal, 0.0, false, 0);
43 TEST_SPECIAL(0.0, max_normal, 0.0, false, 0);
44 TEST_SPECIAL(0.0, -max_normal, 0.0, false, 0);
45
46 // fmod (-0, y) == -0 for y != 0.
47 TEST_SPECIAL(neg_zero, 3.0, neg_zero, false, 0);
48 TEST_SPECIAL(neg_zero, min_denormal, neg_zero, false, 0);
49 TEST_SPECIAL(neg_zero, -min_denormal, neg_zero, false, 0);
50 TEST_SPECIAL(neg_zero, min_normal, neg_zero, false, 0);
51 TEST_SPECIAL(neg_zero, -min_normal, neg_zero, false, 0);
52 TEST_SPECIAL(neg_zero, max_normal, neg_zero, false, 0);
53 TEST_SPECIAL(neg_zero, -max_normal, neg_zero, false, 0);
54
55 // fmod (+inf, y) == aNaN plus invalid exception.
56 TEST_SPECIAL(inf, 3.0, aNaN, true, FE_INVALID);
57 TEST_SPECIAL(inf, -1.1L, aNaN, true, FE_INVALID);
58 TEST_SPECIAL(inf, 0.0, aNaN, true, FE_INVALID);
59 TEST_SPECIAL(inf, neg_zero, aNaN, true, FE_INVALID);
60 TEST_SPECIAL(inf, min_denormal, aNaN, true, FE_INVALID);
61 TEST_SPECIAL(inf, min_normal, aNaN, true, FE_INVALID);
62 TEST_SPECIAL(inf, max_normal, aNaN, true, FE_INVALID);
63 TEST_SPECIAL(inf, inf, aNaN, true, FE_INVALID);
64 TEST_SPECIAL(inf, neg_inf, aNaN, true, FE_INVALID);
65
66 // fmod (-inf, y) == aNaN plus invalid exception.
67 TEST_SPECIAL(neg_inf, 3.0, aNaN, true, FE_INVALID);
68 TEST_SPECIAL(neg_inf, -1.1L, aNaN, true, FE_INVALID);
69 TEST_SPECIAL(neg_inf, 0.0, aNaN, true, FE_INVALID);
70 TEST_SPECIAL(neg_inf, neg_zero, aNaN, true, FE_INVALID);
71 TEST_SPECIAL(neg_inf, min_denormal, aNaN, true, FE_INVALID);
72 TEST_SPECIAL(neg_inf, min_normal, aNaN, true, FE_INVALID);
73 TEST_SPECIAL(neg_inf, max_normal, aNaN, true, FE_INVALID);
74 TEST_SPECIAL(neg_inf, inf, aNaN, true, FE_INVALID);
75 TEST_SPECIAL(neg_inf, neg_inf, aNaN, true, FE_INVALID);
76
77 // fmod (x, +0) == aNaN plus invalid exception.
78 TEST_SPECIAL(3.0, 0.0, aNaN, true, FE_INVALID);
79 TEST_SPECIAL(-1.1L, 0.0, aNaN, true, FE_INVALID);
80 TEST_SPECIAL(0.0, 0.0, aNaN, true, FE_INVALID);
81 TEST_SPECIAL(neg_zero, 0.0, aNaN, true, FE_INVALID);
82 TEST_SPECIAL(min_denormal, 0.0, aNaN, true, FE_INVALID);
83 TEST_SPECIAL(min_normal, 0.0, aNaN, true, FE_INVALID);
84 TEST_SPECIAL(max_normal, 0.0, aNaN, true, FE_INVALID);
85
86 // fmod (x, -0) == aNaN plus invalid exception.
87 TEST_SPECIAL(3.0, neg_zero, aNaN, true, FE_INVALID);
88 TEST_SPECIAL(-1.1L, neg_zero, aNaN, true, FE_INVALID);
89 TEST_SPECIAL(0.0, neg_zero, aNaN, true, FE_INVALID);
90 TEST_SPECIAL(neg_zero, neg_zero, aNaN, true, FE_INVALID);
91 TEST_SPECIAL(min_denormal, neg_zero, aNaN, true, FE_INVALID);
92 TEST_SPECIAL(min_normal, neg_zero, aNaN, true, FE_INVALID);
93 TEST_SPECIAL(max_normal, neg_zero, aNaN, true, FE_INVALID);
94
95 // fmod (x, +inf) == x for x not infinite.
96 TEST_SPECIAL(0.0, inf, 0.0, false, 0);
97 TEST_SPECIAL(neg_zero, inf, neg_zero, false, 0);
98 TEST_SPECIAL(min_denormal, inf, min_denormal, false, 0);
99 TEST_SPECIAL(min_normal, inf, min_normal, false, 0);
100 TEST_SPECIAL(max_normal, inf, max_normal, false, 0);
101 TEST_SPECIAL(3.0, inf, 3.0, false, 0);
102 // fmod (x, -inf) == x for x not infinite.
103 TEST_SPECIAL(0.0, neg_inf, 0.0, false, 0);
104 TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0);
105 TEST_SPECIAL(min_denormal, neg_inf, min_denormal, false, 0);
106 TEST_SPECIAL(min_normal, neg_inf, min_normal, false, 0);
107 TEST_SPECIAL(max_normal, neg_inf, max_normal, false, 0);
108 TEST_SPECIAL(3.0, neg_inf, 3.0, false, 0);
109
110 TEST_SPECIAL(0.0, aNaN, aNaN, false, 0);
111 TEST_SPECIAL(0.0, -aNaN, aNaN, false, 0);
112 TEST_SPECIAL(neg_zero, aNaN, aNaN, false, 0);
113 TEST_SPECIAL(neg_zero, -aNaN, aNaN, false, 0);
114 TEST_SPECIAL(1.0, aNaN, aNaN, false, 0);
115 TEST_SPECIAL(1.0, -aNaN, aNaN, false, 0);
116 TEST_SPECIAL(inf, aNaN, aNaN, false, 0);
117 TEST_SPECIAL(inf, -aNaN, aNaN, false, 0);
118 TEST_SPECIAL(neg_inf, aNaN, aNaN, false, 0);
119 TEST_SPECIAL(neg_inf, -aNaN, aNaN, false, 0);
120 TEST_SPECIAL(0.0, sNaN, aNaN, false, FE_INVALID);
121 TEST_SPECIAL(0.0, -sNaN, aNaN, false, FE_INVALID);
122 TEST_SPECIAL(neg_zero, sNaN, aNaN, false, FE_INVALID);
123 TEST_SPECIAL(neg_zero, -sNaN, aNaN, false, FE_INVALID);
124 TEST_SPECIAL(1.0, sNaN, aNaN, false, FE_INVALID);
125 TEST_SPECIAL(1.0, -sNaN, aNaN, false, FE_INVALID);
126 TEST_SPECIAL(inf, sNaN, aNaN, false, FE_INVALID);
127 TEST_SPECIAL(inf, -sNaN, aNaN, false, FE_INVALID);
128 TEST_SPECIAL(neg_inf, sNaN, aNaN, false, FE_INVALID);
129 TEST_SPECIAL(neg_inf, -sNaN, aNaN, false, FE_INVALID);
130 TEST_SPECIAL(aNaN, 0.0, aNaN, false, 0);
131 TEST_SPECIAL(-aNaN, 0.0, aNaN, false, 0);
132 TEST_SPECIAL(aNaN, neg_zero, aNaN, false, 0);
133 TEST_SPECIAL(-aNaN, neg_zero, aNaN, false, 0);
134 TEST_SPECIAL(aNaN, 1.0, aNaN, false, 0);
135 TEST_SPECIAL(-aNaN, 1.0, aNaN, false, 0);
136 TEST_SPECIAL(aNaN, inf, aNaN, false, 0);
137 TEST_SPECIAL(-aNaN, inf, aNaN, false, 0);
138 TEST_SPECIAL(aNaN, neg_inf, aNaN, false, 0);
139 TEST_SPECIAL(-aNaN, neg_inf, aNaN, false, 0);
140 TEST_SPECIAL(sNaN, 0.0, aNaN, false, FE_INVALID);
141 TEST_SPECIAL(-sNaN, 0.0, aNaN, false, FE_INVALID);
142 TEST_SPECIAL(sNaN, neg_zero, aNaN, false, FE_INVALID);
143 TEST_SPECIAL(-sNaN, neg_zero, aNaN, false, FE_INVALID);
144 TEST_SPECIAL(sNaN, 1.0, aNaN, false, FE_INVALID);
145 TEST_SPECIAL(-sNaN, 1.0, aNaN, false, FE_INVALID);
146 TEST_SPECIAL(sNaN, inf, aNaN, false, FE_INVALID);
147 TEST_SPECIAL(-sNaN, inf, aNaN, false, FE_INVALID);
148 TEST_SPECIAL(sNaN, neg_inf, aNaN, false, FE_INVALID);
149 TEST_SPECIAL(-sNaN, neg_inf, aNaN, false, FE_INVALID);
150 TEST_SPECIAL(aNaN, aNaN, aNaN, false, 0);
151 TEST_SPECIAL(aNaN, -aNaN, aNaN, false, 0);
152 TEST_SPECIAL(-aNaN, aNaN, aNaN, false, 0);
153 TEST_SPECIAL(-aNaN, -aNaN, aNaN, false, 0);
154 TEST_SPECIAL(aNaN, sNaN, aNaN, false, FE_INVALID);
155 TEST_SPECIAL(aNaN, -sNaN, aNaN, false, FE_INVALID);
156 TEST_SPECIAL(-aNaN, sNaN, aNaN, false, FE_INVALID);
157 TEST_SPECIAL(-aNaN, -sNaN, aNaN, false, FE_INVALID);
158 TEST_SPECIAL(sNaN, aNaN, aNaN, false, FE_INVALID);
159 TEST_SPECIAL(sNaN, -aNaN, aNaN, false, FE_INVALID);
160 TEST_SPECIAL(-sNaN, aNaN, aNaN, false, FE_INVALID);
161 TEST_SPECIAL(-sNaN, -aNaN, aNaN, false, FE_INVALID);
162 TEST_SPECIAL(sNaN, sNaN, aNaN, false, FE_INVALID);
163 TEST_SPECIAL(sNaN, -sNaN, aNaN, false, FE_INVALID);
164 TEST_SPECIAL(-sNaN, sNaN, aNaN, false, FE_INVALID);
165 TEST_SPECIAL(-sNaN, -sNaN, aNaN, false, FE_INVALID);
166
167 TEST_SPECIAL(6.5, 2.25L, 2.0L, false, 0);
168 TEST_SPECIAL(-6.5, 2.25L, -2.0L, false, 0);
169 TEST_SPECIAL(6.5, -2.25L, 2.0L, false, 0);
170 TEST_SPECIAL(-6.5, -2.25L, -2.0L, false, 0);
171
172 TEST_SPECIAL(max_normal, max_normal, 0.0, false, 0);
173 TEST_SPECIAL(max_normal, -max_normal, 0.0, false, 0);
174 TEST_SPECIAL(max_normal, min_normal, 0.0, false, 0);
175 TEST_SPECIAL(max_normal, -min_normal, 0.0, false, 0);
176 TEST_SPECIAL(max_normal, min_denormal, 0.0, false, 0);
177 TEST_SPECIAL(max_normal, -min_denormal, 0.0, false, 0);
178 TEST_SPECIAL(-max_normal, max_normal, neg_zero, false, 0);
179 TEST_SPECIAL(-max_normal, -max_normal, neg_zero, false, 0);
180 TEST_SPECIAL(-max_normal, min_normal, neg_zero, false, 0);
181 TEST_SPECIAL(-max_normal, -min_normal, neg_zero, false, 0);
182 TEST_SPECIAL(-max_normal, min_denormal, neg_zero, false, 0);
183 TEST_SPECIAL(-max_normal, -min_denormal, neg_zero, false, 0);
184
185 TEST_SPECIAL(min_normal, max_normal, min_normal, false, 0);
186 TEST_SPECIAL(min_normal, -max_normal, min_normal, false, 0);
187 TEST_SPECIAL(min_normal, min_normal, 0.0, false, 0);
188 TEST_SPECIAL(min_normal, -min_normal, 0.0, false, 0);
189 TEST_SPECIAL(min_normal, min_denormal, 0.0, false, 0);
190 TEST_SPECIAL(min_normal, -min_denormal, 0.0, false, 0);
191 TEST_SPECIAL(-min_normal, max_normal, -min_normal, false, 0);
192 TEST_SPECIAL(-min_normal, -max_normal, -min_normal, false, 0);
193 TEST_SPECIAL(-min_normal, min_normal, neg_zero, false, 0);
194 TEST_SPECIAL(-min_normal, -min_normal, neg_zero, false, 0);
195 TEST_SPECIAL(-min_normal, min_denormal, neg_zero, false, 0);
196 TEST_SPECIAL(-min_normal, -min_denormal, neg_zero, false, 0);
197
198 TEST_SPECIAL(min_denormal, max_normal, min_denormal, false, 0);
199 TEST_SPECIAL(min_denormal, -max_normal, min_denormal, false, 0);
200 TEST_SPECIAL(min_denormal, min_normal, min_denormal, false, 0);
201 TEST_SPECIAL(min_denormal, -min_normal, min_denormal, false, 0);
202 TEST_SPECIAL(min_denormal, min_denormal, 0.0, false, 0);
203 TEST_SPECIAL(min_denormal, -min_denormal, 0.0, false, 0);
204 TEST_SPECIAL(-min_denormal, max_normal, -min_denormal, false, 0);
205 TEST_SPECIAL(-min_denormal, -max_normal, -min_denormal, false, 0);
206 TEST_SPECIAL(-min_denormal, min_normal, -min_denormal, false, 0);
207 TEST_SPECIAL(-min_denormal, -min_normal, -min_denormal, false, 0);
208 TEST_SPECIAL(-min_denormal, min_denormal, neg_zero, false, 0);
209 TEST_SPECIAL(-min_denormal, -min_denormal, neg_zero, false, 0);
210 }
211
212 void testRegularExtreme(FModFunc f) {
213
214 TEST_REGULAR(0x1p127L, 0x3p-149L, 0x1p-149L);
215 TEST_REGULAR(0x1p127L, -0x3p-149L, 0x1p-149L);
216 TEST_REGULAR(0x1p127L, 0x3p-148L, 0x1p-147L);
217 TEST_REGULAR(0x1p127L, -0x3p-148L, 0x1p-147L);
218 TEST_REGULAR(0x1p127L, 0x3p-126L, 0x1p-125L);
219 TEST_REGULAR(0x1p127L, -0x3p-126L, 0x1p-125L);
220 TEST_REGULAR(-0x1p127L, 0x3p-149L, -0x1p-149L);
221 TEST_REGULAR(-0x1p127L, -0x3p-149L, -0x1p-149L);
222 TEST_REGULAR(-0x1p127L, 0x3p-148L, -0x1p-147L);
223 TEST_REGULAR(-0x1p127L, -0x3p-148L, -0x1p-147L);
224 TEST_REGULAR(-0x1p127L, 0x3p-126L, -0x1p-125L);
225 TEST_REGULAR(-0x1p127L, -0x3p-126L, -0x1p-125L);
226
227 if constexpr (sizeof(T) >= sizeof(double)) {
228 TEST_REGULAR(0x1p1023L, 0x3p-1074L, 0x1p-1073L);
229 TEST_REGULAR(0x1p1023L, -0x3p-1074L, 0x1p-1073L);
230 TEST_REGULAR(0x1p1023L, 0x3p-1073L, 0x1p-1073L);
231 TEST_REGULAR(0x1p1023L, -0x3p-1073L, 0x1p-1073L);
232 TEST_REGULAR(0x1p1023L, 0x3p-1022L, 0x1p-1021L);
233 TEST_REGULAR(0x1p1023L, -0x3p-1022L, 0x1p-1021L);
234 TEST_REGULAR(-0x1p1023L, 0x3p-1074L, -0x1p-1073L);
235 TEST_REGULAR(-0x1p1023L, -0x3p-1074L, -0x1p-1073L);
236 TEST_REGULAR(-0x1p1023L, 0x3p-1073L, -0x1p-1073L);
237 TEST_REGULAR(-0x1p1023L, -0x3p-1073L, -0x1p-1073L);
238 TEST_REGULAR(-0x1p1023L, 0x3p-1022L, -0x1p-1021L);
239 TEST_REGULAR(-0x1p1023L, -0x3p-1022L, -0x1p-1021L);
240 }
241 }
242};
243
244#define LIST_FMOD_TESTS(T, func) \
245 using LlvmLibcFmodTest = FmodTest<T>; \
246 TEST_F(LlvmLibcFmodTest, SpecialNumbers) { testSpecialNumbers(&func); } \
247 TEST_F(LlvmLibcFmodTest, RegularExtreme) { testRegularExtreme(&func); }
248
249#endif // LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H
250

source code of libc/test/src/math/FModTest.h