//===-- Single-precision log1p(x) function --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "src/math/log1pf.h" #include "common_constants.h" // Lookup table for (1/f) and log(f) #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FMA.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // This is an algorithm for log10(x) in single precision which is // correctly rounded for all rounding modes. // - An exhaustive test show that when x >= 2^45, log1pf(x) == logf(x) // for all rounding modes. // - When 2^(-6) <= |x| < 2^45, the sum (double(x) + 1.0) is exact, // so we can adapt the correctly rounded algorithm of logf to compute // log(double(x) + 1.0) correctly. For more information about the logf // algorithm, see `libc/src/math/generic/logf.cpp`. // - When |x| < 2^(-6), we use a degree-8 polynomial in double precision // generated with Sollya using the following command: // fpminimax(log(1 + x)/x, 7, [|D...|], [-2^-6; 2^-6]); namespace LIBC_NAMESPACE_DECL { namespace internal { // We don't need to treat denormal and 0 LIBC_INLINE float log(double x) { … } } // namespace internal LLVM_LIBC_FUNCTION(float, log1pf, (float x)) { … } } // namespace LIBC_NAMESPACE_DECL