xref: /aosp_15_r20/external/llvm-libc/test/src/math/exp10f_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Unittests for exp10f ----------------------------------------------===//
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 #include "hdr/math_macros.h"
10 #include "src/__support/FPUtil/FPBits.h"
11 #include "src/errno/libc_errno.h"
12 #include "src/math/exp10f.h"
13 #include "test/UnitTest/FPMatcher.h"
14 #include "test/UnitTest/Test.h"
15 #include "utils/MPFRWrapper/MPFRUtils.h"
16 
17 #include <stdint.h>
18 
19 using LlvmLibcExp10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
20 
21 namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
22 
TEST_F(LlvmLibcExp10fTest,SpecialNumbers)23 TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
24   LIBC_NAMESPACE::libc_errno = 0;
25 
26   EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::exp10f(aNaN));
27   EXPECT_MATH_ERRNO(0);
28 
29   EXPECT_FP_EQ(inf, LIBC_NAMESPACE::exp10f(inf));
30   EXPECT_MATH_ERRNO(0);
31 
32   EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::exp10f(neg_inf));
33   EXPECT_MATH_ERRNO(0);
34 
35   EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::exp10f(0.0f));
36   EXPECT_MATH_ERRNO(0);
37 
38   EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::exp10f(-0.0f));
39   EXPECT_MATH_ERRNO(0);
40 }
41 
TEST_F(LlvmLibcExp10fTest,Overflow)42 TEST_F(LlvmLibcExp10fTest, Overflow) {
43   LIBC_NAMESPACE::libc_errno = 0;
44   EXPECT_FP_EQ_WITH_EXCEPTION(
45       inf, LIBC_NAMESPACE::exp10f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
46   EXPECT_MATH_ERRNO(ERANGE);
47 
48   EXPECT_FP_EQ_WITH_EXCEPTION(
49       inf, LIBC_NAMESPACE::exp10f(FPBits(0x43000000U).get_val()), FE_OVERFLOW);
50   EXPECT_MATH_ERRNO(ERANGE);
51 
52   EXPECT_FP_EQ_WITH_EXCEPTION(
53       inf, LIBC_NAMESPACE::exp10f(FPBits(0x43000001U).get_val()), FE_OVERFLOW);
54   EXPECT_MATH_ERRNO(ERANGE);
55 }
56 
TEST_F(LlvmLibcExp10fTest,Underflow)57 TEST_F(LlvmLibcExp10fTest, Underflow) {
58   LIBC_NAMESPACE::libc_errno = 0;
59   EXPECT_FP_EQ_WITH_EXCEPTION(
60       0.0f, LIBC_NAMESPACE::exp10f(FPBits(0xff7fffffU).get_val()),
61       FE_UNDERFLOW);
62   EXPECT_MATH_ERRNO(ERANGE);
63 
64   float x = FPBits(0xc2cffff8U).get_val();
65   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
66                                  LIBC_NAMESPACE::exp10f(x), 0.5);
67   EXPECT_MATH_ERRNO(ERANGE);
68 
69   x = FPBits(0xc2d00008U).get_val();
70   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
71                                  LIBC_NAMESPACE::exp10f(x), 0.5);
72   EXPECT_MATH_ERRNO(ERANGE);
73 }
74 
TEST_F(LlvmLibcExp10fTest,TrickyInputs)75 TEST_F(LlvmLibcExp10fTest, TrickyInputs) {
76   constexpr int N = 20;
77   constexpr uint32_t INPUTS[N] = {
78       0x325e5bd8, // x = 0x1.bcb7bp-27f
79       0x325e5bd9, // x = 0x1.bcb7b2p-27f
80       0x325e5bda, // x = 0x1.bcb7b4p-27f
81       0x3d14d956, // x = 0x1.29b2acp-5f
82       0x4116498a, // x = 0x1.2c9314p3f
83       0x4126f431, // x = 0x1.4de862p3f
84       0x4187d13c, // x = 0x1.0fa278p4f
85       0x4203e9da, // x = 0x1.07d3b4p5f
86       0x420b5f5d, // x = 0x1.16bebap5f
87       0x42349e35, // x = 0x1.693c6ap5f
88       0x3f800000, // x = 1.0f
89       0x40000000, // x = 2.0f
90       0x40400000, // x = 3.0f
91       0x40800000, // x = 4.0f
92       0x40a00000, // x = 5.0f
93       0x40c00000, // x = 6.0f
94       0x40e00000, // x = 7.0f
95       0x41000000, // x = 8.0f
96       0x41100000, // x = 9.0f
97       0x41200000, // x = 10.0f
98   };
99   for (int i = 0; i < N; ++i) {
100     LIBC_NAMESPACE::libc_errno = 0;
101     float x = FPBits(INPUTS[i]).get_val();
102     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
103                                    LIBC_NAMESPACE::exp10f(x), 0.5);
104     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, -x,
105                                    LIBC_NAMESPACE::exp10f(-x), 0.5);
106   }
107 }
108 
TEST_F(LlvmLibcExp10fTest,InFloatRange)109 TEST_F(LlvmLibcExp10fTest, InFloatRange) {
110   constexpr uint32_t COUNT = 100'000;
111   constexpr uint32_t STEP = UINT32_MAX / COUNT;
112   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
113     float x = FPBits(v).get_val();
114     if (FPBits(v).is_nan() || FPBits(v).is_inf())
115       continue;
116     LIBC_NAMESPACE::libc_errno = 0;
117     float result = LIBC_NAMESPACE::exp10f(x);
118 
119     // If the computation resulted in an error or did not produce valid result
120     // in the single-precision floating point range, then ignore comparing with
121     // MPFR result as MPFR can still produce valid results because of its
122     // wider precision.
123     if (FPBits(result).is_nan() || FPBits(result).is_inf() ||
124         LIBC_NAMESPACE::libc_errno != 0)
125       continue;
126     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
127                                    LIBC_NAMESPACE::exp10f(x), 0.5);
128   }
129 }
130