12
12
13
13
// <cmath>
14
14
15
+ #include < array>
15
16
#include < cmath>
16
17
#include < limits>
17
18
#include < type_traits>
18
19
#include < cassert>
19
20
21
+ #include " fp_compare.h"
20
22
#include " test_macros.h"
21
23
#include " hexfloat.h"
22
24
#include " truncate_fp.h"
25
+ #include " type_algorithms.h"
23
26
24
27
// convertible to int/float/double/etc
25
28
template <class T , int N=0 >
@@ -1113,6 +1116,56 @@ void test_fmin()
1113
1116
assert (std::fmin (1 ,0 ) == 0 );
1114
1117
}
1115
1118
1119
+ #if TEST_STD_VER >= 17
1120
+ struct TestHypot3 {
1121
+ template <class Real >
1122
+ void operator ()() const {
1123
+ const auto check = [](Real elem, Real abs_tol) {
1124
+ assert (std::isfinite (std::hypot (elem, Real (0 ), Real (0 ))));
1125
+ assert (fptest_close (std::hypot (elem, Real (0 ), Real (0 )), elem, abs_tol));
1126
+ assert (std::isfinite (std::hypot (elem, elem, Real (0 ))));
1127
+ assert (fptest_close (std::hypot (elem, elem, Real (0 )), std::sqrt (Real (2 )) * elem, abs_tol));
1128
+ assert (std::isfinite (std::hypot (elem, elem, elem)));
1129
+ assert (fptest_close (std::hypot (elem, elem, elem), std::sqrt (Real (3 )) * elem, abs_tol));
1130
+ };
1131
+
1132
+ { // check for overflow
1133
+ const auto [elem, abs_tol] = []() -> std::array<Real, 2 > {
1134
+ if constexpr (std::is_same_v<Real, float >)
1135
+ return {1e20f, 1e16f};
1136
+ else if constexpr (std::is_same_v<Real, double >)
1137
+ return {1e300 , 1e287 };
1138
+ else { // long double
1139
+ # if __DBL_MAX_EXP__ == __LDBL_MAX_EXP__
1140
+ return {1e300l, 1e287l}; // 64-bit
1141
+ # else
1142
+ return {1e4000l, 1e3985l}; // 80- or 128-bit
1143
+ # endif
1144
+ }
1145
+ }();
1146
+ check (elem, abs_tol);
1147
+ }
1148
+
1149
+ { // check for underflow
1150
+ const auto [elem, abs_tol] = []() -> std::array<Real, 2 > {
1151
+ if constexpr (std::is_same_v<Real, float >)
1152
+ return {1e-20f , 1e-24f };
1153
+ else if constexpr (std::is_same_v<Real, double >)
1154
+ return {1e-287 , 1e-300 };
1155
+ else { // long double
1156
+ # if __DBL_MAX_EXP__ == __LDBL_MAX_EXP__
1157
+ return {1e-287l , 1e-300l }; // 64-bit
1158
+ # else
1159
+ return {1e-3985l , 1e-4000l }; // 80- or 128-bit
1160
+ # endif
1161
+ }
1162
+ }();
1163
+ check (elem, abs_tol);
1164
+ }
1165
+ }
1166
+ };
1167
+ #endif
1168
+
1116
1169
void test_hypot ()
1117
1170
{
1118
1171
static_assert ((std::is_same<decltype (std::hypot ((float )0 , (float )0 )), float >::value), " " );
@@ -1135,25 +1188,31 @@ void test_hypot()
1135
1188
static_assert ((std::is_same<decltype (hypot (Ambiguous (), Ambiguous ())), Ambiguous>::value), " " );
1136
1189
assert (std::hypot (3 ,4 ) == 5 );
1137
1190
1138
- #if TEST_STD_VER > 14
1139
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (float )0 , (float )0 )), float >::value), " " );
1140
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (bool )0 , (float )0 )), double >::value), " " );
1141
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (unsigned short )0 , (double )0 )), double >::value), " " );
1142
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (int )0 , (long double )0 )), long double >::value), " " );
1143
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (double )0 , (long )0 )), double >::value), " " );
1144
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (long double )0 , (unsigned long )0 )), long double >::value), " " );
1145
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (int )0 , (long long )0 )), double >::value), " " );
1146
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (int )0 , (unsigned long long )0 )), double >::value), " " );
1147
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (double )0 , (double )0 )), double >::value), " " );
1148
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (long double )0 , (long double )0 )), long double >::value), " " );
1149
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (float )0 , (double )0 )), double >::value), " " );
1150
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (float )0 , (long double )0 )), long double >::value), " " );
1151
- static_assert ((std::is_same<decltype (std::hypot ((float )0 , (double )0 , (long double )0 )), long double >::value), " " );
1152
- static_assert ((std::is_same<decltype (std::hypot ((int )0 , (int )0 , (int )0 )), double >::value), " " );
1153
- static_assert ((std::is_same<decltype (hypot (Ambiguous (), Ambiguous (), Ambiguous ())), Ambiguous>::value), " " );
1191
+ #if TEST_STD_VER >= 17
1192
+ // clang-format off
1193
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (float )0 , (float )0 )), float >));
1194
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (bool )0 , (float )0 )), double >));
1195
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (unsigned short )0 , (double )0 )), double >));
1196
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (int )0 , (long double )0 )), long double >));
1197
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (double )0 , (long )0 )), double >));
1198
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (long double )0 , (unsigned long )0 )), long double >));
1199
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (int )0 , (long long )0 )), double >));
1200
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (int )0 , (unsigned long long )0 )), double >));
1201
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (double )0 , (double )0 )), double >));
1202
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (long double )0 , (long double )0 )), long double >));
1203
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (float )0 , (double )0 )), double >));
1204
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (float )0 , (long double )0 )), long double >));
1205
+ static_assert ((std::is_same_v<decltype (std::hypot ((float )0 , (double )0 , (long double )0 )), long double >));
1206
+ static_assert ((std::is_same_v<decltype (std::hypot ((int )0 , (int )0 , (int )0 )), double >));
1207
+ static_assert ((std::is_same_v<decltype (hypot (Ambiguous (), Ambiguous (), Ambiguous ())), Ambiguous>));
1208
+ // clang-format on
1154
1209
1155
1210
assert (std::hypot (2 ,3 ,6 ) == 7 );
1156
1211
assert (std::hypot (1 ,4 ,8 ) == 9 );
1212
+
1213
+ // Check for undue over-/underflows of intermediate results.
1214
+ // See discussion at https://github.com/llvm/llvm-project/issues/92782.
1215
+ types::for_each (types::floating_point_types (), TestHypot3 ());
1157
1216
#endif
1158
1217
}
1159
1218
0 commit comments