xref: /aosp_15_r20/external/llvm-libc/test/src/stdfix/RoundTest.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Utility class to test fixed-point round -----------------*- 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/Test.h"
10*71db0c75SAndroid Build Coastguard Worker 
11*71db0c75SAndroid Build Coastguard Worker #include "src/__support/fixed_point/fx_rep.h"
12*71db0c75SAndroid Build Coastguard Worker 
13*71db0c75SAndroid Build Coastguard Worker template <typename T> class RoundTest : public LIBC_NAMESPACE::testing::Test {
14*71db0c75SAndroid Build Coastguard Worker 
15*71db0c75SAndroid Build Coastguard Worker   using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
16*71db0c75SAndroid Build Coastguard Worker   static constexpr T zero = FXRep::ZERO();
17*71db0c75SAndroid Build Coastguard Worker   static constexpr T min = FXRep::MIN();
18*71db0c75SAndroid Build Coastguard Worker   static constexpr T max = FXRep::MAX();
19*71db0c75SAndroid Build Coastguard Worker   static constexpr T half = static_cast<T>(0.5);
20*71db0c75SAndroid Build Coastguard Worker   static constexpr T neg_half = static_cast<T>(-0.5);
21*71db0c75SAndroid Build Coastguard Worker   static constexpr T one =
22*71db0c75SAndroid Build Coastguard Worker       (FXRep::INTEGRAL_LEN > 0) ? static_cast<T>(1) : FXRep::MAX();
23*71db0c75SAndroid Build Coastguard Worker   static constexpr T neg_one = static_cast<T>(-1);
24*71db0c75SAndroid Build Coastguard Worker   static constexpr T eps = FXRep::EPS();
25*71db0c75SAndroid Build Coastguard Worker 
26*71db0c75SAndroid Build Coastguard Worker public:
27*71db0c75SAndroid Build Coastguard Worker   typedef T (*RoundFunc)(T, int);
28*71db0c75SAndroid Build Coastguard Worker 
testSpecialNumbers(RoundFunc func)29*71db0c75SAndroid Build Coastguard Worker   void testSpecialNumbers(RoundFunc func) {
30*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(zero, func(zero, FXRep::FRACTION_LEN - 5));
31*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(min, func(min, 0));
32*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(max, func(max, FXRep::FRACTION_LEN));
33*71db0c75SAndroid Build Coastguard Worker 
34*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(one, func(half, 0));
35*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(half, func(half, 1));
36*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(half, func(half, FXRep::FRACTION_LEN));
37*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(one, func(half + eps, 0));
38*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(half, func(half + eps, 1));
39*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(half, func(half + eps, 2));
40*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(zero, func(half - eps, 0));
41*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(half, func(half - eps, 1));
42*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(half, func(half - eps, 2));
43*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(eps, func(eps, FXRep::FRACTION_LEN + 10));
44*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(eps << 1, func(eps, FXRep::FRACTION_LEN - 1));
45*71db0c75SAndroid Build Coastguard Worker     EXPECT_EQ(zero, func(eps, FXRep::FRACTION_LEN - 2));
46*71db0c75SAndroid Build Coastguard Worker 
47*71db0c75SAndroid Build Coastguard Worker     if constexpr (FXRep::SIGN_LEN) {
48*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(zero, func(neg_half, 0));
49*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(neg_half, func(neg_half, 1));
50*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(neg_half, func(neg_half, 3));
51*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(zero, func(neg_half + eps, 0));
52*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(neg_half, func(neg_half + eps, 1));
53*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(neg_half, func(neg_half + eps, 2));
54*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(neg_one, func(neg_half - eps, 0));
55*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(neg_half, func(neg_half - eps, 1));
56*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(neg_half, func(neg_half - eps, 2));
57*71db0c75SAndroid Build Coastguard Worker       EXPECT_EQ(-eps, func(-eps, FXRep::FRACTION_LEN + 10));
58*71db0c75SAndroid Build Coastguard Worker     }
59*71db0c75SAndroid Build Coastguard Worker   }
60*71db0c75SAndroid Build Coastguard Worker };
61*71db0c75SAndroid Build Coastguard Worker 
62*71db0c75SAndroid Build Coastguard Worker #define LIST_ROUND_TESTS(T, func)                                              \
63*71db0c75SAndroid Build Coastguard Worker   using LlvmLibcRoundTest = RoundTest<T>;                                      \
64*71db0c75SAndroid Build Coastguard Worker   TEST_F(LlvmLibcRoundTest, SpecialNumbers) { testSpecialNumbers(&func); }     \
65*71db0c75SAndroid Build Coastguard Worker   static_assert(true, "Require semicolon.")
66