xref: /llvm-project/libc/test/src/math/exp10f_test.cpp (revision f8f5b17564cb839101ba99390bcecc564de57e65)
1a752460dSTue Ly //===-- Unittests for exp10f ----------------------------------------------===//
2a752460dSTue Ly //
3a752460dSTue Ly // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a752460dSTue Ly // See https://llvm.org/LICENSE.txt for license information.
5a752460dSTue Ly // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a752460dSTue Ly //
7a752460dSTue Ly //===----------------------------------------------------------------------===//
8a752460dSTue Ly 
95748ad84Slntue #include "hdr/math_macros.h"
10a752460dSTue Ly #include "src/__support/FPUtil/FPBits.h"
1131c39439STue Ly #include "src/errno/libc_errno.h"
12a752460dSTue Ly #include "src/math/exp10f.h"
13af1315c2SSiva Chandra Reddy #include "test/UnitTest/FPMatcher.h"
14af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h"
15a752460dSTue Ly #include "utils/MPFRWrapper/MPFRUtils.h"
16a752460dSTue Ly 
17a752460dSTue Ly #include <stdint.h>
18a752460dSTue Ly 
193fd5113cSlntue using LlvmLibcExp10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
203fd5113cSlntue 
21b6bc9d72SGuillaume Chatelet namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
22a752460dSTue Ly 
233fd5113cSlntue TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
243eb1e6d8Smichaelrj-google   LIBC_NAMESPACE::libc_errno = 0;
25a752460dSTue Ly 
26b6bc9d72SGuillaume Chatelet   EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::exp10f(aNaN));
27a752460dSTue Ly   EXPECT_MATH_ERRNO(0);
28a752460dSTue Ly 
29b6bc9d72SGuillaume Chatelet   EXPECT_FP_EQ(inf, LIBC_NAMESPACE::exp10f(inf));
30a752460dSTue Ly   EXPECT_MATH_ERRNO(0);
31a752460dSTue Ly 
32b6bc9d72SGuillaume Chatelet   EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::exp10f(neg_inf));
33a752460dSTue Ly   EXPECT_MATH_ERRNO(0);
34a752460dSTue Ly 
35b6bc9d72SGuillaume Chatelet   EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::exp10f(0.0f));
36a752460dSTue Ly   EXPECT_MATH_ERRNO(0);
37a752460dSTue Ly 
38b6bc9d72SGuillaume Chatelet   EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::exp10f(-0.0f));
39a752460dSTue Ly   EXPECT_MATH_ERRNO(0);
40a752460dSTue Ly }
41a752460dSTue Ly 
423fd5113cSlntue TEST_F(LlvmLibcExp10fTest, Overflow) {
433eb1e6d8Smichaelrj-google   LIBC_NAMESPACE::libc_errno = 0;
440aa9593cSTue Ly   EXPECT_FP_EQ_WITH_EXCEPTION(
452856db0dSGuillaume Chatelet       inf, LIBC_NAMESPACE::exp10f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
46a752460dSTue Ly   EXPECT_MATH_ERRNO(ERANGE);
47a752460dSTue Ly 
480aa9593cSTue Ly   EXPECT_FP_EQ_WITH_EXCEPTION(
492856db0dSGuillaume Chatelet       inf, LIBC_NAMESPACE::exp10f(FPBits(0x43000000U).get_val()), FE_OVERFLOW);
50a752460dSTue Ly   EXPECT_MATH_ERRNO(ERANGE);
51a752460dSTue Ly 
520aa9593cSTue Ly   EXPECT_FP_EQ_WITH_EXCEPTION(
532856db0dSGuillaume Chatelet       inf, LIBC_NAMESPACE::exp10f(FPBits(0x43000001U).get_val()), FE_OVERFLOW);
540aa9593cSTue Ly   EXPECT_MATH_ERRNO(ERANGE);
550aa9593cSTue Ly }
560aa9593cSTue Ly 
573fd5113cSlntue TEST_F(LlvmLibcExp10fTest, Underflow) {
583eb1e6d8Smichaelrj-google   LIBC_NAMESPACE::libc_errno = 0;
590aa9593cSTue Ly   EXPECT_FP_EQ_WITH_EXCEPTION(
602856db0dSGuillaume Chatelet       0.0f, LIBC_NAMESPACE::exp10f(FPBits(0xff7fffffU).get_val()),
612856db0dSGuillaume Chatelet       FE_UNDERFLOW);
620aa9593cSTue Ly   EXPECT_MATH_ERRNO(ERANGE);
630aa9593cSTue Ly 
642856db0dSGuillaume Chatelet   float x = FPBits(0xc2cffff8U).get_val();
650aa9593cSTue Ly   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
66b6bc9d72SGuillaume Chatelet                                  LIBC_NAMESPACE::exp10f(x), 0.5);
670aa9593cSTue Ly   EXPECT_MATH_ERRNO(ERANGE);
680aa9593cSTue Ly 
692856db0dSGuillaume Chatelet   x = FPBits(0xc2d00008U).get_val();
700aa9593cSTue Ly   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
71b6bc9d72SGuillaume Chatelet                                  LIBC_NAMESPACE::exp10f(x), 0.5);
72a752460dSTue Ly   EXPECT_MATH_ERRNO(ERANGE);
73a752460dSTue Ly }
74a752460dSTue Ly 
753fd5113cSlntue TEST_F(LlvmLibcExp10fTest, TrickyInputs) {
76a752460dSTue Ly   constexpr int N = 20;
77a752460dSTue Ly   constexpr uint32_t INPUTS[N] = {
78a752460dSTue Ly       0x325e5bd8, // x = 0x1.bcb7bp-27f
79a752460dSTue Ly       0x325e5bd9, // x = 0x1.bcb7b2p-27f
80a752460dSTue Ly       0x325e5bda, // x = 0x1.bcb7b4p-27f
81a752460dSTue Ly       0x3d14d956, // x = 0x1.29b2acp-5f
82a752460dSTue Ly       0x4116498a, // x = 0x1.2c9314p3f
83a752460dSTue Ly       0x4126f431, // x = 0x1.4de862p3f
84a752460dSTue Ly       0x4187d13c, // x = 0x1.0fa278p4f
85a752460dSTue Ly       0x4203e9da, // x = 0x1.07d3b4p5f
86a752460dSTue Ly       0x420b5f5d, // x = 0x1.16bebap5f
87a752460dSTue Ly       0x42349e35, // x = 0x1.693c6ap5f
88a752460dSTue Ly       0x3f800000, // x = 1.0f
89a752460dSTue Ly       0x40000000, // x = 2.0f
90a752460dSTue Ly       0x40400000, // x = 3.0f
91a752460dSTue Ly       0x40800000, // x = 4.0f
92a752460dSTue Ly       0x40a00000, // x = 5.0f
93a752460dSTue Ly       0x40c00000, // x = 6.0f
94a752460dSTue Ly       0x40e00000, // x = 7.0f
95a752460dSTue Ly       0x41000000, // x = 8.0f
96a752460dSTue Ly       0x41100000, // x = 9.0f
97a752460dSTue Ly       0x41200000, // x = 10.0f
98a752460dSTue Ly   };
99a752460dSTue Ly   for (int i = 0; i < N; ++i) {
1003eb1e6d8Smichaelrj-google     LIBC_NAMESPACE::libc_errno = 0;
1012856db0dSGuillaume Chatelet     float x = FPBits(INPUTS[i]).get_val();
102a752460dSTue Ly     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
103b6bc9d72SGuillaume Chatelet                                    LIBC_NAMESPACE::exp10f(x), 0.5);
104a752460dSTue Ly     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, -x,
105b6bc9d72SGuillaume Chatelet                                    LIBC_NAMESPACE::exp10f(-x), 0.5);
106a752460dSTue Ly   }
107a752460dSTue Ly }
108a752460dSTue Ly 
1093fd5113cSlntue TEST_F(LlvmLibcExp10fTest, InFloatRange) {
110ae5c4724SGuillaume Chatelet   constexpr uint32_t COUNT = 100'000;
111a752460dSTue Ly   constexpr uint32_t STEP = UINT32_MAX / COUNT;
112a752460dSTue Ly   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
1132856db0dSGuillaume Chatelet     float x = FPBits(v).get_val();
114*f8f5b175SNhat Nguyen     if (FPBits(v).is_nan() || FPBits(v).is_inf())
115a752460dSTue Ly       continue;
1163eb1e6d8Smichaelrj-google     LIBC_NAMESPACE::libc_errno = 0;
117b6bc9d72SGuillaume Chatelet     float result = LIBC_NAMESPACE::exp10f(x);
118a752460dSTue Ly 
119a752460dSTue Ly     // If the computation resulted in an error or did not produce valid result
120a752460dSTue Ly     // in the single-precision floating point range, then ignore comparing with
121a752460dSTue Ly     // MPFR result as MPFR can still produce valid results because of its
122a752460dSTue Ly     // wider precision.
123*f8f5b175SNhat Nguyen     if (FPBits(result).is_nan() || FPBits(result).is_inf() ||
124*f8f5b175SNhat Nguyen         LIBC_NAMESPACE::libc_errno != 0)
125a752460dSTue Ly       continue;
126a752460dSTue Ly     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
127b6bc9d72SGuillaume Chatelet                                    LIBC_NAMESPACE::exp10f(x), 0.5);
128a752460dSTue Ly   }
129a752460dSTue Ly }
130