xref: /aosp_15_r20/external/llvm-libc/test/src/stdfix/ISqrtTest.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Utility class to test integer sqrt ----------------------*- C++ -*-===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker 
9*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/FPMatcher.h"
10*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h"
11*71db0c75SAndroid Build Coastguard Worker 
12*71db0c75SAndroid Build Coastguard Worker #include "src/__support/CPP/bit.h"
13*71db0c75SAndroid Build Coastguard Worker #include "src/__support/FPUtil/BasicOperations.h"
14*71db0c75SAndroid Build Coastguard Worker #include "src/__support/FPUtil/sqrt.h"
15*71db0c75SAndroid Build Coastguard Worker #include "src/__support/fixed_point/fx_rep.h"
16*71db0c75SAndroid Build Coastguard Worker #include "src/__support/fixed_point/sqrt.h"
17*71db0c75SAndroid Build Coastguard Worker 
18*71db0c75SAndroid Build Coastguard Worker template <typename T> class ISqrtTest : public LIBC_NAMESPACE::testing::Test {
19*71db0c75SAndroid Build Coastguard Worker 
20*71db0c75SAndroid Build Coastguard Worker   using OutType =
21*71db0c75SAndroid Build Coastguard Worker       typename LIBC_NAMESPACE::fixed_point::internal::SqrtConfig<T>::OutType;
22*71db0c75SAndroid Build Coastguard Worker   using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<OutType>;
23*71db0c75SAndroid Build Coastguard Worker   static constexpr OutType zero = FXRep::ZERO();
24*71db0c75SAndroid Build Coastguard Worker   static constexpr OutType one = static_cast<OutType>(1);
25*71db0c75SAndroid Build Coastguard Worker   static constexpr OutType eps = FXRep::EPS();
26*71db0c75SAndroid Build Coastguard Worker 
27*71db0c75SAndroid Build Coastguard Worker public:
28*71db0c75SAndroid Build Coastguard Worker   typedef OutType (*SqrtFunc)(T);
29*71db0c75SAndroid Build Coastguard Worker 
testSpecificInput(T input,OutType result,double expected,double tolerance)30*71db0c75SAndroid Build Coastguard Worker   void testSpecificInput(T input, OutType result, double expected,
31*71db0c75SAndroid Build Coastguard Worker                          double tolerance) {
32*71db0c75SAndroid Build Coastguard Worker     double y_d = static_cast<double>(result);
33*71db0c75SAndroid Build Coastguard Worker     double errors = LIBC_NAMESPACE::fputil::abs((y_d / expected) - 1.0);
34*71db0c75SAndroid Build Coastguard Worker     if (errors > tolerance) {
35*71db0c75SAndroid Build Coastguard Worker       // Print out the failure input and output.
36*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(input, T(0));
37*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(result, zero);
38*71db0c75SAndroid Build Coastguard Worker     }
39*71db0c75SAndroid Build Coastguard Worker     ASSERT_TRUE(errors <= tolerance);
40*71db0c75SAndroid Build Coastguard Worker   }
41*71db0c75SAndroid Build Coastguard Worker 
testSpecialNumbers(SqrtFunc func)42*71db0c75SAndroid Build Coastguard Worker   void testSpecialNumbers(SqrtFunc func) {
43*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(zero, func(T(0)));
44*71db0c75SAndroid Build Coastguard Worker 
45*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(one, func(T(1)));
46*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<OutType>(2.0), func(T(4)));
47*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<OutType>(4.0), func(T(16)));
48*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<OutType>(16.0), func(T(256)));
49*71db0c75SAndroid Build Coastguard Worker 
50*71db0c75SAndroid Build Coastguard Worker     constexpr int COUNT = 255;
51*71db0c75SAndroid Build Coastguard Worker     constexpr double ERR = 3.0 * static_cast<double>(eps);
52*71db0c75SAndroid Build Coastguard Worker     double x_d = 0.0;
53*71db0c75SAndroid Build Coastguard Worker     T x = 0;
54*71db0c75SAndroid Build Coastguard Worker     for (int i = 0; i < COUNT; ++i) {
55*71db0c75SAndroid Build Coastguard Worker       x_d += 1.0;
56*71db0c75SAndroid Build Coastguard Worker       ++x;
57*71db0c75SAndroid Build Coastguard Worker       OutType result = func(x);
58*71db0c75SAndroid Build Coastguard Worker       double expected = LIBC_NAMESPACE::fputil::sqrt<double>(x_d);
59*71db0c75SAndroid Build Coastguard Worker       testSpecificInput(x, result, expected, ERR);
60*71db0c75SAndroid Build Coastguard Worker     }
61*71db0c75SAndroid Build Coastguard Worker   }
62*71db0c75SAndroid Build Coastguard Worker };
63*71db0c75SAndroid Build Coastguard Worker 
64*71db0c75SAndroid Build Coastguard Worker #define LIST_ISQRT_TESTS(Name, T, func)                                        \
65*71db0c75SAndroid Build Coastguard Worker   using LlvmLibcISqrt##Name##Test = ISqrtTest<T>;                              \
66*71db0c75SAndroid Build Coastguard Worker   TEST_F(LlvmLibcISqrt##Name##Test, SpecialNumbers) {                          \
67*71db0c75SAndroid Build Coastguard Worker     testSpecialNumbers(&func);                                                 \
68*71db0c75SAndroid Build Coastguard Worker   }                                                                            \
69*71db0c75SAndroid Build Coastguard Worker   static_assert(true, "Require semicolon.")
70