1 | //===-- Utility class to test different flavors of nearbyint ----*- C++ -*-===// |
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_NEARBYINTTEST_H |
10 | #define LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H |
11 | |
12 | #include "hdr/fenv_macros.h" |
13 | #include "src/__support/FPUtil/FEnvImpl.h" |
14 | #include "src/__support/FPUtil/FPBits.h" |
15 | #include "test/UnitTest/FPMatcher.h" |
16 | #include "test/UnitTest/Test.h" |
17 | |
18 | using LIBC_NAMESPACE::Sign; |
19 | |
20 | static constexpr int ROUNDING_MODES[4] = {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO, |
21 | FE_TONEAREST}; |
22 | |
23 | template <typename T> |
24 | class NearbyIntTestTemplate : public LIBC_NAMESPACE::testing::Test { |
25 | |
26 | DECLARE_SPECIAL_CONSTANTS(T) |
27 | |
28 | public: |
29 | typedef T (*NearbyIntFunc)(T); |
30 | |
31 | void testNaN(NearbyIntFunc func) { |
32 | EXPECT_FP_EQ_ALL_ROUNDING(func(aNaN), aNaN); |
33 | } |
34 | |
35 | void testInfinities(NearbyIntFunc func) { |
36 | EXPECT_FP_EQ_ALL_ROUNDING(func(inf), inf); |
37 | EXPECT_FP_EQ_ALL_ROUNDING(func(neg_inf), neg_inf); |
38 | } |
39 | |
40 | void testZeroes(NearbyIntFunc func) { |
41 | EXPECT_FP_EQ_ALL_ROUNDING(func(zero), zero); |
42 | EXPECT_FP_EQ_ALL_ROUNDING(func(neg_zero), neg_zero); |
43 | } |
44 | |
45 | void testIntegers(NearbyIntFunc func) { |
46 | EXPECT_FP_EQ_ALL_ROUNDING(func(T(1.0)), T(1.0)); |
47 | EXPECT_FP_EQ_ALL_ROUNDING(func(T(-1.0)), T(-1.0)); |
48 | |
49 | EXPECT_FP_EQ_ALL_ROUNDING(func(T(1234.0)), T(1234.0)); |
50 | EXPECT_FP_EQ_ALL_ROUNDING(func(T(-1234.0)), T(-1234.0)); |
51 | |
52 | EXPECT_FP_EQ_ALL_ROUNDING(func(T(10.0)), T(10.0)); |
53 | EXPECT_FP_EQ_ALL_ROUNDING(func(T(-10.0)), T(-10.0)); |
54 | |
55 | FPBits ints_start(T(0)); |
56 | ints_start.set_biased_exponent(FPBits::SIG_LEN + FPBits::EXP_BIAS); |
57 | T expected = ints_start.get_val(); |
58 | EXPECT_FP_EQ_ALL_ROUNDING(func(expected), expected); |
59 | } |
60 | |
61 | void testSubnormalToNearest(NearbyIntFunc func) { |
62 | ASSERT_FP_EQ(func(min_denormal), zero); |
63 | ASSERT_FP_EQ(func(-min_denormal), neg_zero); |
64 | } |
65 | |
66 | void testSubnormalTowardZero(NearbyIntFunc func) { |
67 | EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(func(min_denormal), zero); |
68 | EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(func(-min_denormal), neg_zero); |
69 | } |
70 | |
71 | void testSubnormalToPosInf(NearbyIntFunc func) { |
72 | EXPECT_FP_EQ_ROUNDING_UPWARD(func(min_denormal), FPBits::one().get_val()); |
73 | EXPECT_FP_EQ_ROUNDING_UPWARD(func(-min_denormal), neg_zero); |
74 | } |
75 | |
76 | void testSubnormalToNegInf(NearbyIntFunc func) { |
77 | T negative_one = FPBits::one(Sign::NEG).get_val(); |
78 | EXPECT_FP_EQ_ROUNDING_DOWNWARD(func(min_denormal), zero); |
79 | EXPECT_FP_EQ_ROUNDING_DOWNWARD(func(-min_denormal), negative_one); |
80 | } |
81 | }; |
82 | |
83 | #define LIST_NEARBYINT_TESTS(T, func) \ |
84 | using LlvmLibcNearbyIntTest = NearbyIntTestTemplate<T>; \ |
85 | TEST_F(LlvmLibcNearbyIntTest, TestNaN) { testNaN(&func); } \ |
86 | TEST_F(LlvmLibcNearbyIntTest, TestInfinities) { testInfinities(&func); } \ |
87 | TEST_F(LlvmLibcNearbyIntTest, TestZeroes) { testZeroes(&func); } \ |
88 | TEST_F(LlvmLibcNearbyIntTest, TestIntegers) { testIntegers(&func); } \ |
89 | TEST_F(LlvmLibcNearbyIntTest, TestSubnormalToNearest) { \ |
90 | testSubnormalToNearest(&func); \ |
91 | } \ |
92 | TEST_F(LlvmLibcNearbyIntTest, TestSubnormalTowardZero) { \ |
93 | testSubnormalTowardZero(&func); \ |
94 | } \ |
95 | TEST_F(LlvmLibcNearbyIntTest, TestSubnormalToPosInf) { \ |
96 | testSubnormalToPosInf(&func); \ |
97 | } \ |
98 | TEST_F(LlvmLibcNearbyIntTest, TestSubnormalToNegInf) { \ |
99 | testSubnormalToNegInf(&func); \ |
100 | } |
101 | |
102 | #endif // LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H |
103 | |