1 //===-- Utility class to test different flavors of hypot ------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_TEST_SRC_MATH_HYPOTTEST_H
10 #define LLVM_LIBC_TEST_SRC_MATH_HYPOTTEST_H
12 #include "src/__support/FPUtil/FPBits.h"
13 #include "test/UnitTest/FEnvSafeTest.h"
14 #include "test/UnitTest/FPMatcher.h"
15 #include "test/UnitTest/Test.h"
16 #include "utils/MPFRWrapper/MPFRUtils.h"
18 #include "hdr/math_macros.h"
20 using LIBC_NAMESPACE::Sign
;
22 namespace mpfr
= LIBC_NAMESPACE::testing::mpfr
;
25 class HypotTestTemplate
: public LIBC_NAMESPACE::testing::FEnvSafeTest
{
27 using Func
= T (*)(T
, T
);
28 using FPBits
= LIBC_NAMESPACE::fputil::FPBits
<T
>;
30 using StorageType
= typename
FPBits::StorageType
;
31 const T nan
= FPBits::quiet_nan().get_val();
32 const T inf
= FPBits::inf().get_val();
33 const T neg_inf
= FPBits::inf(Sign::NEG
).get_val();
34 const T zero
= FPBits::zero().get_val();
35 const T neg_zero
= FPBits::zero(Sign::NEG
).get_val();
36 const T max_normal
= FPBits::max_normal().get_val();
37 const T min_normal
= FPBits::min_normal().get_val();
38 const T max_subnormal
= FPBits::max_subnormal().get_val();
39 const T min_subnormal
= FPBits::min_subnormal().get_val();
41 static constexpr StorageType MAX_NORMAL
= FPBits::max_normal().uintval();
42 static constexpr StorageType MIN_NORMAL
= FPBits::min_normal().uintval();
43 static constexpr StorageType MAX_SUBNORMAL
=
44 FPBits::max_subnormal().uintval();
45 static constexpr StorageType MIN_SUBNORMAL
=
46 FPBits::min_subnormal().uintval();
49 void test_special_numbers(Func func
) {
51 const T SpecialInputs
[N
] = {inf
, neg_inf
, zero
,
52 neg_zero
, max_normal
, min_normal
,
53 max_subnormal
, min_subnormal
, -max_normal
,
54 -min_normal
, -max_subnormal
, -min_subnormal
};
56 EXPECT_FP_EQ(func(inf
, nan
), inf
);
57 EXPECT_FP_EQ(func(nan
, neg_inf
), inf
);
58 EXPECT_FP_EQ(func(nan
, nan
), nan
);
59 EXPECT_FP_EQ(func(nan
, zero
), nan
);
60 EXPECT_FP_EQ(func(neg_zero
, nan
), nan
);
62 for (int i
= 0; i
< N
; ++i
) {
63 for (int j
= 0; j
< N
; ++j
) {
64 mpfr::BinaryInput
<T
> input
{SpecialInputs
[i
], SpecialInputs
[j
]};
65 EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Hypot
, input
,
66 func(SpecialInputs
[i
], SpecialInputs
[j
]),
72 void test_subnormal_range(Func func
) {
73 constexpr StorageType COUNT
= 10'001;
74 for (unsigned scale
= 0; scale
< 4; ++scale
) {
75 StorageType max_value
= MAX_SUBNORMAL
<< scale
;
76 StorageType step
= (max_value
- MIN_SUBNORMAL
) / COUNT
;
77 for (int signs
= 0; signs
< 4; ++signs
) {
78 for (StorageType v
= MIN_SUBNORMAL
, w
= max_value
;
79 v
<= max_value
&& w
>= MIN_SUBNORMAL
; v
+= step
, w
-= step
) {
80 T x
= FPBits(v
).get_val(), y
= FPBits(w
).get_val();
88 mpfr::BinaryInput
<T
> input
{x
, y
};
89 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Hypot
, input
,
96 void test_normal_range(Func func
) {
97 constexpr StorageType COUNT
= 10'001;
98 constexpr StorageType STEP
= (MAX_NORMAL
- MIN_NORMAL
) / COUNT
;
99 for (int signs
= 0; signs
< 4; ++signs
) {
100 for (StorageType v
= MIN_NORMAL
, w
= MAX_NORMAL
;
101 v
<= MAX_NORMAL
&& w
>= MIN_NORMAL
; v
+= STEP
, w
-= STEP
) {
102 T x
= FPBits(v
).get_val(), y
= FPBits(w
).get_val();
103 if (signs
% 2 == 1) {
110 mpfr::BinaryInput
<T
> input
{x
, y
};
111 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Hypot
, input
,
117 void test_input_list(Func func
, int n
, const mpfr::BinaryInput
<T
> *inputs
) {
118 for (int i
= 0; i
< n
; ++i
) {
119 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Hypot
, inputs
[i
],
120 func(inputs
[i
].x
, inputs
[i
].y
), 0.5);
125 #endif // LLVM_LIBC_TEST_SRC_MATH_HYPOTTEST_H