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 "utils/UnitTest/FPMatcher.h" 15 #include "utils/UnitTest/Test.h" 16 17 #include <limits> 18 #include <math.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 __llvm_libc::fputil::clear_except(FE_ALL_EXCEPT) 25 26 #define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, false, 0) 27 28 template <typename T> class FmodTest : public __llvm_libc::testing::Test { 29 30 DECLARE_SPECIAL_CONSTANTS(T) 31 32 public: 33 typedef T (*FModFunc)(T, T); 34 testSpecialNumbers(FModFunc f)35 void testSpecialNumbers(FModFunc f) { 36 using nl = std::numeric_limits<T>; 37 38 // fmod (+0, y) == +0 for y != 0. 39 TEST_SPECIAL(0.0, 3.0, 0.0, false, 0); 40 TEST_SPECIAL(0.0, nl::denorm_min(), 0.0, false, 0); 41 TEST_SPECIAL(0.0, -nl::denorm_min(), 0.0, false, 0); 42 TEST_SPECIAL(0.0, nl::min(), 0.0, false, 0); 43 TEST_SPECIAL(0.0, -nl::min(), 0.0, false, 0); 44 TEST_SPECIAL(0.0, nl::max(), 0.0, false, 0); 45 TEST_SPECIAL(0.0, -nl::max(), 0.0, false, 0); 46 47 // fmod (-0, y) == -0 for y != 0. 48 TEST_SPECIAL(neg_zero, 3.0, neg_zero, false, 0); 49 TEST_SPECIAL(neg_zero, nl::denorm_min(), neg_zero, false, 0); 50 TEST_SPECIAL(neg_zero, -nl::denorm_min(), neg_zero, false, 0); 51 TEST_SPECIAL(neg_zero, nl::min(), neg_zero, false, 0); 52 TEST_SPECIAL(neg_zero, -nl::min(), neg_zero, false, 0); 53 TEST_SPECIAL(neg_zero, nl::max(), neg_zero, false, 0); 54 TEST_SPECIAL(neg_zero, -nl::max(), neg_zero, false, 0); 55 56 // fmod (+inf, y) == nl::quiet_NaN() plus invalid exception. 57 TEST_SPECIAL(inf, 3.0, nl::quiet_NaN(), true, FE_INVALID); 58 TEST_SPECIAL(inf, -1.1L, nl::quiet_NaN(), true, FE_INVALID); 59 TEST_SPECIAL(inf, 0.0, nl::quiet_NaN(), true, FE_INVALID); 60 TEST_SPECIAL(inf, neg_zero, nl::quiet_NaN(), true, FE_INVALID); 61 TEST_SPECIAL(inf, nl::denorm_min(), nl::quiet_NaN(), true, FE_INVALID); 62 TEST_SPECIAL(inf, nl::min(), nl::quiet_NaN(), true, FE_INVALID); 63 TEST_SPECIAL(inf, nl::max(), nl::quiet_NaN(), true, FE_INVALID); 64 TEST_SPECIAL(inf, inf, nl::quiet_NaN(), true, FE_INVALID); 65 TEST_SPECIAL(inf, neg_inf, nl::quiet_NaN(), true, FE_INVALID); 66 67 // fmod (-inf, y) == nl::quiet_NaN() plus invalid exception. 68 TEST_SPECIAL(neg_inf, 3.0, nl::quiet_NaN(), true, FE_INVALID); 69 TEST_SPECIAL(neg_inf, -1.1L, nl::quiet_NaN(), true, FE_INVALID); 70 TEST_SPECIAL(neg_inf, 0.0, nl::quiet_NaN(), true, FE_INVALID); 71 TEST_SPECIAL(neg_inf, neg_zero, nl::quiet_NaN(), true, FE_INVALID); 72 TEST_SPECIAL(neg_inf, nl::denorm_min(), nl::quiet_NaN(), true, FE_INVALID); 73 TEST_SPECIAL(neg_inf, nl::min(), nl::quiet_NaN(), true, FE_INVALID); 74 TEST_SPECIAL(neg_inf, nl::max(), nl::quiet_NaN(), true, FE_INVALID); 75 TEST_SPECIAL(neg_inf, inf, nl::quiet_NaN(), true, FE_INVALID); 76 TEST_SPECIAL(neg_inf, neg_inf, nl::quiet_NaN(), true, FE_INVALID); 77 78 // fmod (x, +0) == nl::quiet_NaN() plus invalid exception. 79 TEST_SPECIAL(3.0, 0.0, nl::quiet_NaN(), true, FE_INVALID); 80 TEST_SPECIAL(-1.1L, 0.0, nl::quiet_NaN(), true, FE_INVALID); 81 TEST_SPECIAL(0.0, 0.0, nl::quiet_NaN(), true, FE_INVALID); 82 TEST_SPECIAL(neg_zero, 0.0, nl::quiet_NaN(), true, FE_INVALID); 83 TEST_SPECIAL(nl::denorm_min(), 0.0, nl::quiet_NaN(), true, FE_INVALID); 84 TEST_SPECIAL(nl::min(), 0.0, nl::quiet_NaN(), true, FE_INVALID); 85 TEST_SPECIAL(nl::max(), 0.0, nl::quiet_NaN(), true, FE_INVALID); 86 87 // fmod (x, -0) == nl::quiet_NaN() plus invalid exception. 88 TEST_SPECIAL(3.0, neg_zero, nl::quiet_NaN(), true, FE_INVALID); 89 TEST_SPECIAL(-1.1L, neg_zero, nl::quiet_NaN(), true, FE_INVALID); 90 TEST_SPECIAL(0.0, neg_zero, nl::quiet_NaN(), true, FE_INVALID); 91 TEST_SPECIAL(neg_zero, neg_zero, nl::quiet_NaN(), true, FE_INVALID); 92 TEST_SPECIAL(nl::denorm_min(), neg_zero, nl::quiet_NaN(), true, FE_INVALID); 93 TEST_SPECIAL(nl::min(), neg_zero, nl::quiet_NaN(), true, FE_INVALID); 94 TEST_SPECIAL(nl::max(), neg_zero, nl::quiet_NaN(), true, FE_INVALID); 95 96 // fmod (x, +inf) == x for x not infinite. 97 TEST_SPECIAL(0.0, inf, 0.0, false, 0); 98 TEST_SPECIAL(neg_zero, inf, neg_zero, false, 0); 99 TEST_SPECIAL(nl::denorm_min(), inf, nl::denorm_min(), false, 0); 100 TEST_SPECIAL(nl::min(), inf, nl::min(), false, 0); 101 TEST_SPECIAL(nl::max(), inf, nl::max(), false, 0); 102 TEST_SPECIAL(3.0, inf, 3.0, false, 0); 103 // fmod (x, -inf) == x for x not infinite. 104 TEST_SPECIAL(0.0, neg_inf, 0.0, false, 0); 105 TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0); 106 TEST_SPECIAL(nl::denorm_min(), neg_inf, nl::denorm_min(), false, 0); 107 TEST_SPECIAL(nl::min(), neg_inf, nl::min(), false, 0); 108 TEST_SPECIAL(nl::max(), neg_inf, nl::max(), false, 0); 109 TEST_SPECIAL(3.0, neg_inf, 3.0, false, 0); 110 111 TEST_SPECIAL(0.0, nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 112 TEST_SPECIAL(0.0, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 113 TEST_SPECIAL(neg_zero, nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 114 TEST_SPECIAL(neg_zero, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 115 TEST_SPECIAL(1.0, nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 116 TEST_SPECIAL(1.0, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 117 TEST_SPECIAL(inf, nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 118 TEST_SPECIAL(inf, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 119 TEST_SPECIAL(neg_inf, nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 120 TEST_SPECIAL(neg_inf, -nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 121 TEST_SPECIAL(0.0, nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID); 122 TEST_SPECIAL(0.0, -nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID); 123 TEST_SPECIAL(neg_zero, nl::signaling_NaN(), nl::quiet_NaN(), false, 124 FE_INVALID); 125 TEST_SPECIAL(neg_zero, -nl::signaling_NaN(), nl::quiet_NaN(), false, 126 FE_INVALID); 127 TEST_SPECIAL(1.0, nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID); 128 TEST_SPECIAL(1.0, -nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID); 129 TEST_SPECIAL(inf, nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID); 130 TEST_SPECIAL(inf, -nl::signaling_NaN(), nl::quiet_NaN(), false, FE_INVALID); 131 TEST_SPECIAL(neg_inf, nl::signaling_NaN(), nl::quiet_NaN(), false, 132 FE_INVALID); 133 TEST_SPECIAL(neg_inf, -nl::signaling_NaN(), nl::quiet_NaN(), false, 134 FE_INVALID); 135 TEST_SPECIAL(nl::quiet_NaN(), 0.0, nl::quiet_NaN(), false, 0); 136 TEST_SPECIAL(-nl::quiet_NaN(), 0.0, nl::quiet_NaN(), false, 0); 137 TEST_SPECIAL(nl::quiet_NaN(), neg_zero, nl::quiet_NaN(), false, 0); 138 TEST_SPECIAL(-nl::quiet_NaN(), neg_zero, nl::quiet_NaN(), false, 0); 139 TEST_SPECIAL(nl::quiet_NaN(), 1.0, nl::quiet_NaN(), false, 0); 140 TEST_SPECIAL(-nl::quiet_NaN(), 1.0, nl::quiet_NaN(), false, 0); 141 TEST_SPECIAL(nl::quiet_NaN(), inf, nl::quiet_NaN(), false, 0); 142 TEST_SPECIAL(-nl::quiet_NaN(), inf, nl::quiet_NaN(), false, 0); 143 TEST_SPECIAL(nl::quiet_NaN(), neg_inf, nl::quiet_NaN(), false, 0); 144 TEST_SPECIAL(-nl::quiet_NaN(), neg_inf, nl::quiet_NaN(), false, 0); 145 TEST_SPECIAL(nl::signaling_NaN(), 0.0, nl::quiet_NaN(), false, FE_INVALID); 146 TEST_SPECIAL(-nl::signaling_NaN(), 0.0, nl::quiet_NaN(), false, FE_INVALID); 147 TEST_SPECIAL(nl::signaling_NaN(), neg_zero, nl::quiet_NaN(), false, 148 FE_INVALID); 149 TEST_SPECIAL(-nl::signaling_NaN(), neg_zero, nl::quiet_NaN(), false, 150 FE_INVALID); 151 TEST_SPECIAL(nl::signaling_NaN(), 1.0, nl::quiet_NaN(), false, FE_INVALID); 152 TEST_SPECIAL(-nl::signaling_NaN(), 1.0, nl::quiet_NaN(), false, FE_INVALID); 153 TEST_SPECIAL(nl::signaling_NaN(), inf, nl::quiet_NaN(), false, FE_INVALID); 154 TEST_SPECIAL(-nl::signaling_NaN(), inf, nl::quiet_NaN(), false, FE_INVALID); 155 TEST_SPECIAL(nl::signaling_NaN(), neg_inf, nl::quiet_NaN(), false, 156 FE_INVALID); 157 TEST_SPECIAL(-nl::signaling_NaN(), neg_inf, nl::quiet_NaN(), false, 158 FE_INVALID); 159 TEST_SPECIAL(nl::quiet_NaN(), nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 160 TEST_SPECIAL(nl::quiet_NaN(), -nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 161 TEST_SPECIAL(-nl::quiet_NaN(), nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 162 TEST_SPECIAL(-nl::quiet_NaN(), -nl::quiet_NaN(), nl::quiet_NaN(), false, 0); 163 TEST_SPECIAL(nl::quiet_NaN(), nl::signaling_NaN(), nl::quiet_NaN(), false, 164 FE_INVALID); 165 TEST_SPECIAL(nl::quiet_NaN(), -nl::signaling_NaN(), nl::quiet_NaN(), false, 166 FE_INVALID); 167 TEST_SPECIAL(-nl::quiet_NaN(), nl::signaling_NaN(), nl::quiet_NaN(), false, 168 FE_INVALID); 169 TEST_SPECIAL(-nl::quiet_NaN(), -nl::signaling_NaN(), nl::quiet_NaN(), false, 170 FE_INVALID); 171 TEST_SPECIAL(nl::signaling_NaN(), nl::quiet_NaN(), nl::quiet_NaN(), false, 172 FE_INVALID); 173 TEST_SPECIAL(nl::signaling_NaN(), -nl::quiet_NaN(), nl::quiet_NaN(), false, 174 FE_INVALID); 175 TEST_SPECIAL(-nl::signaling_NaN(), nl::quiet_NaN(), nl::quiet_NaN(), false, 176 FE_INVALID); 177 TEST_SPECIAL(-nl::signaling_NaN(), -nl::quiet_NaN(), nl::quiet_NaN(), false, 178 FE_INVALID); 179 TEST_SPECIAL(nl::signaling_NaN(), nl::signaling_NaN(), nl::quiet_NaN(), 180 false, FE_INVALID); 181 TEST_SPECIAL(nl::signaling_NaN(), -nl::signaling_NaN(), nl::quiet_NaN(), 182 false, FE_INVALID); 183 TEST_SPECIAL(-nl::signaling_NaN(), nl::signaling_NaN(), nl::quiet_NaN(), 184 false, FE_INVALID); 185 TEST_SPECIAL(-nl::signaling_NaN(), -nl::signaling_NaN(), nl::quiet_NaN(), 186 false, FE_INVALID); 187 188 TEST_SPECIAL(6.5, 2.25L, 2.0L, false, 0); 189 TEST_SPECIAL(-6.5, 2.25L, -2.0L, false, 0); 190 TEST_SPECIAL(6.5, -2.25L, 2.0L, false, 0); 191 TEST_SPECIAL(-6.5, -2.25L, -2.0L, false, 0); 192 193 TEST_SPECIAL(nl::max(), nl::max(), 0.0, false, 0); 194 TEST_SPECIAL(nl::max(), -nl::max(), 0.0, false, 0); 195 TEST_SPECIAL(nl::max(), nl::min(), 0.0, false, 0); 196 TEST_SPECIAL(nl::max(), -nl::min(), 0.0, false, 0); 197 TEST_SPECIAL(nl::max(), nl::denorm_min(), 0.0, false, 0); 198 TEST_SPECIAL(nl::max(), -nl::denorm_min(), 0.0, false, 0); 199 TEST_SPECIAL(-nl::max(), nl::max(), neg_zero, false, 0); 200 TEST_SPECIAL(-nl::max(), -nl::max(), neg_zero, false, 0); 201 TEST_SPECIAL(-nl::max(), nl::min(), neg_zero, false, 0); 202 TEST_SPECIAL(-nl::max(), -nl::min(), neg_zero, false, 0); 203 TEST_SPECIAL(-nl::max(), nl::denorm_min(), neg_zero, false, 0); 204 TEST_SPECIAL(-nl::max(), -nl::denorm_min(), neg_zero, false, 0); 205 206 TEST_SPECIAL(nl::min(), nl::max(), nl::min(), false, 0); 207 TEST_SPECIAL(nl::min(), -nl::max(), nl::min(), false, 0); 208 TEST_SPECIAL(nl::min(), nl::min(), 0.0, false, 0); 209 TEST_SPECIAL(nl::min(), -nl::min(), 0.0, false, 0); 210 TEST_SPECIAL(nl::min(), nl::denorm_min(), 0.0, false, 0); 211 TEST_SPECIAL(nl::min(), -nl::denorm_min(), 0.0, false, 0); 212 TEST_SPECIAL(-nl::min(), nl::max(), -nl::min(), false, 0); 213 TEST_SPECIAL(-nl::min(), -nl::max(), -nl::min(), false, 0); 214 TEST_SPECIAL(-nl::min(), nl::min(), neg_zero, false, 0); 215 TEST_SPECIAL(-nl::min(), -nl::min(), neg_zero, false, 0); 216 TEST_SPECIAL(-nl::min(), nl::denorm_min(), neg_zero, false, 0); 217 TEST_SPECIAL(-nl::min(), -nl::denorm_min(), neg_zero, false, 0); 218 219 TEST_SPECIAL(nl::denorm_min(), nl::max(), nl::denorm_min(), false, 0); 220 TEST_SPECIAL(nl::denorm_min(), -nl::max(), nl::denorm_min(), false, 0); 221 TEST_SPECIAL(nl::denorm_min(), nl::min(), nl::denorm_min(), false, 0); 222 TEST_SPECIAL(nl::denorm_min(), -nl::min(), nl::denorm_min(), false, 0); 223 TEST_SPECIAL(nl::denorm_min(), nl::denorm_min(), 0.0, false, 0); 224 TEST_SPECIAL(nl::denorm_min(), -nl::denorm_min(), 0.0, false, 0); 225 TEST_SPECIAL(-nl::denorm_min(), nl::max(), -nl::denorm_min(), false, 0); 226 TEST_SPECIAL(-nl::denorm_min(), -nl::max(), -nl::denorm_min(), false, 0); 227 TEST_SPECIAL(-nl::denorm_min(), nl::min(), -nl::denorm_min(), false, 0); 228 TEST_SPECIAL(-nl::denorm_min(), -nl::min(), -nl::denorm_min(), false, 0); 229 TEST_SPECIAL(-nl::denorm_min(), nl::denorm_min(), neg_zero, false, 0); 230 TEST_SPECIAL(-nl::denorm_min(), -nl::denorm_min(), neg_zero, false, 0); 231 } 232 testRegularExtreme(FModFunc f)233 void testRegularExtreme(FModFunc f) { 234 235 TEST_REGULAR(0x1p127L, 0x3p-149L, 0x1p-149L); 236 TEST_REGULAR(0x1p127L, -0x3p-149L, 0x1p-149L); 237 TEST_REGULAR(0x1p127L, 0x3p-148L, 0x1p-147L); 238 TEST_REGULAR(0x1p127L, -0x3p-148L, 0x1p-147L); 239 TEST_REGULAR(0x1p127L, 0x3p-126L, 0x1p-125L); 240 TEST_REGULAR(0x1p127L, -0x3p-126L, 0x1p-125L); 241 TEST_REGULAR(-0x1p127L, 0x3p-149L, -0x1p-149L); 242 TEST_REGULAR(-0x1p127L, -0x3p-149L, -0x1p-149L); 243 TEST_REGULAR(-0x1p127L, 0x3p-148L, -0x1p-147L); 244 TEST_REGULAR(-0x1p127L, -0x3p-148L, -0x1p-147L); 245 TEST_REGULAR(-0x1p127L, 0x3p-126L, -0x1p-125L); 246 TEST_REGULAR(-0x1p127L, -0x3p-126L, -0x1p-125L); 247 248 if constexpr (sizeof(T) >= sizeof(double)) { 249 TEST_REGULAR(0x1p1023L, 0x3p-1074L, 0x1p-1073L); 250 TEST_REGULAR(0x1p1023L, -0x3p-1074L, 0x1p-1073L); 251 TEST_REGULAR(0x1p1023L, 0x3p-1073L, 0x1p-1073L); 252 TEST_REGULAR(0x1p1023L, -0x3p-1073L, 0x1p-1073L); 253 TEST_REGULAR(0x1p1023L, 0x3p-1022L, 0x1p-1021L); 254 TEST_REGULAR(0x1p1023L, -0x3p-1022L, 0x1p-1021L); 255 TEST_REGULAR(-0x1p1023L, 0x3p-1074L, -0x1p-1073L); 256 TEST_REGULAR(-0x1p1023L, -0x3p-1074L, -0x1p-1073L); 257 TEST_REGULAR(-0x1p1023L, 0x3p-1073L, -0x1p-1073L); 258 TEST_REGULAR(-0x1p1023L, -0x3p-1073L, -0x1p-1073L); 259 TEST_REGULAR(-0x1p1023L, 0x3p-1022L, -0x1p-1021L); 260 TEST_REGULAR(-0x1p1023L, -0x3p-1022L, -0x1p-1021L); 261 } 262 } 263 }; 264 265 #define LIST_FMOD_TESTS(T, func) \ 266 using LlvmLibcFmodTest = FmodTest<T>; \ 267 TEST_F(LlvmLibcFmodTest, SpecialNumbers) { testSpecialNumbers(&func); } \ 268 TEST_F(LlvmLibcFmodTest, RegularExtreme) { testRegularExtreme(&func); } 269 270 #endif // LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H 271