brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.3 KiB · 9a0c4a1 Raw
87 lines · plain
1//  (C) Copyright Matt Borland 2021.2//  Use, modification and distribution are subject to the3//  Boost Software License, Version 1.0. (See accompanying file4//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)5 6#ifndef BOOST_MATH_CCMATH_LOGB_HPP7#define BOOST_MATH_CCMATH_LOGB_HPP8 9#include <boost/math/ccmath/detail/config.hpp>10 11#ifdef BOOST_MATH_NO_CCMATH12#error "The header <boost/math/logb.hpp> can only be used in C++17 and later."13#endif14 15#include <boost/math/ccmath/frexp.hpp>16#include <boost/math/ccmath/isinf.hpp>17#include <boost/math/ccmath/isnan.hpp>18#include <boost/math/ccmath/abs.hpp>19 20namespace boost::math::ccmath {21 22namespace detail {23 24// The value of the exponent returned by std::logb is always 1 less than the exponent returned by 25// std::frexp because of the different normalization requirements: for the exponent e returned by std::logb, 26// |arg*r^-e| is between 1 and r (typically between 1 and 2), but for the exponent e returned by std::frexp, 27// |arg*2^-e| is between 0.5 and 1. 28template <typename T>29constexpr T logb_impl(T arg) noexcept30{31    int exp = 0;32    boost::math::ccmath::frexp(arg, &exp);33 34    return static_cast<T>(exp - 1);35}36 37} // Namespace detail38 39template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, bool> = true>40constexpr Real logb(Real arg) noexcept41{42    if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg))43    {44        if (boost::math::ccmath::abs(arg) == Real(0))45        {46            return -std::numeric_limits<Real>::infinity();47        }48        else if (boost::math::ccmath::isinf(arg))49        {50            return std::numeric_limits<Real>::infinity();51        }52        else if (boost::math::ccmath::isnan(arg))53        {54            return arg;55        }56        57        return boost::math::ccmath::detail::logb_impl(arg);58    }59    else60    {61        using std::logb;62        return logb(arg);63    }64}65 66template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>67constexpr double logb(Z arg) noexcept68{69    return boost::math::ccmath::logb(static_cast<double>(arg));70}71 72constexpr float logbf(float arg) noexcept73{74    return boost::math::ccmath::logb(arg);75}76 77#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS78constexpr long double logbl(long double arg) noexcept79{80    return boost::math::ccmath::logb(arg);81}82#endif83 84} // Namespaces85 86#endif // BOOST_MATH_CCMATH_LOGB_HPP87