1// (C) Copyright Matt Borland 2021.
2// (C) Copyright John Maddock 2021.
3// Use, modification and distribution are subject to the
4// Boost Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#ifndef BOOST_MATH_CCMATH_LDEXP_HPP
8#define BOOST_MATH_CCMATH_LDEXP_HPP
9
10#include <boost/math/ccmath/detail/config.hpp>
11
12#ifdef BOOST_MATH_NO_CCMATH
13#error "The header <boost/math/ldexp.hpp> can only be used in C++17 and later."
14#endif
15
16#include <stdexcept>
17#include <boost/math/ccmath/abs.hpp>
18#include <boost/math/ccmath/isinf.hpp>
19#include <boost/math/ccmath/isnan.hpp>
20
21namespace boost::math::ccmath {
22
23namespace detail {
24
25template <typename Real>
26inline constexpr Real ldexp_impl(Real arg, int exp) noexcept
27{
28 while(exp > 0)
29 {
30 arg *= 2;
31 --exp;
32 }
33 while(exp < 0)
34 {
35 arg /= 2;
36 ++exp;
37 }
38
39 return arg;
40}
41
42} // Namespace detail
43
44template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, bool> = true>
45inline constexpr Real ldexp(Real arg, int exp) noexcept
46{
47 if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg))
48 {
49 return boost::math::ccmath::abs(arg) == Real(0) ? arg :
50 (boost::math::ccmath::isinf)(arg) ? arg :
51 (boost::math::ccmath::isnan)(arg) ? arg :
52 boost::math::ccmath::detail::ldexp_impl(arg, exp);
53 }
54 else
55 {
56 using std::ldexp;
57 return ldexp(arg, exp);
58 }
59}
60
61template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
62inline constexpr double ldexp(Z arg, int exp) noexcept
63{
64 return boost::math::ccmath::ldexp(arg: static_cast<double>(arg), exp);
65}
66
67inline constexpr float ldexpf(float arg, int exp) noexcept
68{
69 return boost::math::ccmath::ldexp(arg, exp);
70}
71
72#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
73inline constexpr long double ldexpl(long double arg, int exp) noexcept
74{
75 return boost::math::ccmath::ldexp(arg, exp);
76}
77#endif
78
79} // Namespaces
80
81#endif // BOOST_MATH_CCMATH_LDEXP_HPP
82

source code of boost/libs/math/include/boost/math/ccmath/ldexp.hpp