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