1 //===-- Utility class to test different flavors of hypot ------------------===//
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_HYPOTTEST_H
10 #define LLVM_LIBC_TEST_SRC_MATH_HYPOTTEST_H
11 
12 #include "src/__support/FPUtil/FPBits.h"
13 #include "src/__support/FPUtil/Hypot.h"
14 #include "utils/MPFRWrapper/MPFRUtils.h"
15 #include "utils/UnitTest/FPMatcher.h"
16 #include "utils/UnitTest/Test.h"
17 
18 #include <math.h>
19 
20 namespace mpfr = __llvm_libc::testing::mpfr;
21 
22 template <typename T>
23 class HypotTestTemplate : public __llvm_libc::testing::Test {
24 private:
25   using Func = T (*)(T, T);
26   using FPBits = __llvm_libc::fputil::FPBits<T>;
27   using UIntType = typename FPBits::UIntType;
28   const T nan = T(__llvm_libc::fputil::FPBits<T>::buildNaN(1));
29   const T inf = T(__llvm_libc::fputil::FPBits<T>::inf());
30   const T negInf = T(__llvm_libc::fputil::FPBits<T>::negInf());
31   const T zero = T(__llvm_libc::fputil::FPBits<T>::zero());
32   const T negZero = T(__llvm_libc::fputil::FPBits<T>::negZero());
33 
34 public:
35   void testSpecialNumbers(Func func) {
36     EXPECT_FP_EQ(func(inf, nan), inf);
37     EXPECT_FP_EQ(func(nan, negInf), inf);
38     EXPECT_FP_EQ(func(zero, inf), inf);
39     EXPECT_FP_EQ(func(negInf, negZero), inf);
40 
41     EXPECT_FP_EQ(func(nan, nan), nan);
42     EXPECT_FP_EQ(func(nan, zero), nan);
43     EXPECT_FP_EQ(func(negZero, nan), nan);
44 
45     EXPECT_FP_EQ(func(negZero, zero), zero);
46   }
47 
48   void testSubnormalRange(Func func) {
49     constexpr UIntType count = 1000001;
50     constexpr UIntType step =
51         (FPBits::maxSubnormal - FPBits::minSubnormal) / count;
52     for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal;
53          v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal;
54          v += step, w -= step) {
55       T x = T(FPBits(v)), y = T(FPBits(w));
56       T result = func(x, y);
57       mpfr::BinaryInput<T> input{x, y};
58       ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
59     }
60   }
61 
62   void testNormalRange(Func func) {
63     constexpr UIntType count = 1000001;
64     constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count;
65     for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal;
66          v <= FPBits::maxNormal && w >= FPBits::minNormal;
67          v += step, w -= step) {
68       T x = T(FPBits(v)), y = T(FPBits(w));
69       T result = func(x, y);
70       mpfr::BinaryInput<T> input{x, y};
71       ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
72     }
73   }
74 };
75 
76 #endif // LLVM_LIBC_TEST_SRC_MATH_HYPOTTEST_H
77