Skip to content

Commit

Permalink
Begin to streamline ccmath
Browse files Browse the repository at this point in the history
  • Loading branch information
ckormanyos committed Dec 30, 2024
1 parent 6ac4ed9 commit 37e28bf
Show file tree
Hide file tree
Showing 12 changed files with 217 additions and 251 deletions.
26 changes: 4 additions & 22 deletions include/boost/multiprecision/cpp_df_qf/cpp_df_qf_detail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,17 @@
#ifndef BOOST_MP_CPP_DF_QF_DETAIL_2023_01_02_HPP
#define BOOST_MP_CPP_DF_QF_DETAIL_2023_01_02_HPP

#include <cmath>
#include <limits>
#include <tuple>
#include <utility>

#include <boost/config.hpp>
#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath.hpp>

#ifdef BOOST_HAS_FLOAT128
#include <quadmath.h>
#endif
#include <cmath>
#include <limits>
#include <tuple>
#include <utility>

namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail {

inline float floor_of_constituent(float x) { return ::floorf(x); }
inline double floor_of_constituent(double x) { return ::floor (x); }
inline long double floor_of_constituent(long double x) { return ::floorl(x); }
#if defined(BOOST_HAS_FLOAT128)
inline ::boost::float128_type floor_of_constituent(::boost::float128_type x) { return ::floorq(x); }
#endif

inline float log_of_constituent(float x) { return ::logf(x); }
inline double log_of_constituent(double x) { return ::log (x); }
inline long double log_of_constituent(long double x) { return ::logl(x); }
#if defined(BOOST_HAS_FLOAT128)
inline ::boost::float128_type log_of_constituent(::boost::float128_type x) { return ::logq(x); }
#endif

inline constexpr float split (float) { return static_cast<float> (1U + static_cast<unsigned long long>(static_cast<unsigned long long>(1U) << static_cast<unsigned>((cpp_df_qf_detail::ccmath::numeric_limits<float >::digits + 1) / 2))); }
inline constexpr double split (double) { return static_cast<double> (1U + static_cast<unsigned long long>(static_cast<unsigned long long>(1U) << static_cast<unsigned>((cpp_df_qf_detail::ccmath::numeric_limits<double >::digits + 1) / 2))); }
inline constexpr long double split (long double) { return static_cast<long double>(1U + static_cast<unsigned long long>(static_cast<unsigned long long>(1U) << static_cast<unsigned>((cpp_df_qf_detail::ccmath::numeric_limits<long double >::digits + 1) / 2))); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,22 @@
#ifndef BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_2023_01_07_HPP
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_2023_01_07_HPP

#include <boost/config.hpp>

#ifdef BOOST_HAS_FLOAT128
#include <quadmath.h>
#endif

#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_fabs.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_floor.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_fma.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_fpclassify.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_frexp.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isinf.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isnan.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_ldexp.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_limits.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_log.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_sqrt.hpp>

#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_2023_01_07_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@

namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {

template <class FloatingPointType>
constexpr FloatingPointType fabs(FloatingPointType x)
template <class Real>
constexpr Real fabs(Real x)
{
return (cpp_df_qf_detail::ccmath::isnan(x)) ? cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::quiet_NaN() :
(x == static_cast<FloatingPointType>(-0)) ? static_cast<FloatingPointType>(0) :
(x >= 0) ? x : -x;
return (cpp_df_qf_detail::ccmath::isnan(x)) ? cpp_df_qf_detail::ccmath::numeric_limits<Real>::quiet_NaN()
: (x == static_cast<Real>(-0)) ? static_cast<Real>(0)
: (x >= 0) ? x
: -x;
};

} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2024.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FLOOR_2024_12_30_HPP
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FLOOR_2024_12_30_HPP

#include <cmath>
#include <type_traits>

namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {

namespace detail {

#if defined(BOOST_HAS_FLOAT128)
template <class T>
auto floor_impl(T x) -> typename ::std::enable_if<::std::is_same<T, ::boost::float128_type>::value, T>::type
{
return ::floorq(x);
}
#endif

template <class T>
auto floor_impl(T x) -> typename ::std::enable_if<::std::is_floating_point<T>::value, T>::type
{
// Default to the regular std::floor function.
using std::floor;

return floor(x);
}

} // namespace detail

template <typename Real>
auto floor(Real x) -> Real
{
return cpp_df_qf_detail::ccmath::detail::floor_impl<Real>(x);
}

} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath

#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FLOOR_2024_12_30_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,61 @@
#ifndef BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FMA_2024_12_17_HPP
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FMA_2024_12_17_HPP

#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isnan.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isinf.hpp>
#include <cmath>
#include <type_traits>

namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {

namespace unsafe {

namespace detail {

#if defined(BOOST_HAS_FLOAT128)
template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, ::boost::float128_type>::value, T>::type
{
return ::fmaq(x);
}
#endif

#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER)
template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, float>::value, T>::type
{
return __builtin_fmaf(x, y, z);
}

template <class T>
constexpr T fma_imp(T x, T y, T z) noexcept
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, double>::value, T>::type
{
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER)
return __builtin_fma(x, y, z);
}

BOOST_IF_CONSTEXPR(::std::is_same<T, float>::value)
{
return __builtin_fmaf(x, y, z);
}
else BOOST_IF_CONSTEXPR(::std::is_same<T, double>::value)
{
return __builtin_fma(x, y, z);
}
else BOOST_IF_CONSTEXPR(::std::is_same<T, long double>::value)
{
return __builtin_fmal(x, y, z);
}
#endif
template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, long double>::value, T>::type
{
return __builtin_fmal(x, y, z);
}
#else
template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_floating_point<T>::value, T>::type
{
// Default to the written-out operations.

// If we can't use compiler intrinsics hope that -fma flag optimizes this call to fma instruction
return (x * y) + z;
};
}
#endif

} // namespace detail

template <typename Real>
constexpr Real fma(Real x, Real y, Real z) noexcept
auto fma(Real x, Real y, Real z) noexcept -> Real
{
if (x == 0 && cpp_df_qf_detail::ccmath::isinf(y))
{
return std::numeric_limits<Real>::quiet_NaN();
}
else if (y == 0 && cpp_df_qf_detail::ccmath::isinf(x))
{
return std::numeric_limits<Real>::quiet_NaN();
}
else if (cpp_df_qf_detail::ccmath::isnan(x))
{
return std::numeric_limits<Real>::quiet_NaN();
}
else if (cpp_df_qf_detail::ccmath::isnan(y))
{
return std::numeric_limits<Real>::quiet_NaN();
}
else if (cpp_df_qf_detail::ccmath::isnan(z))
{
return std::numeric_limits<Real>::quiet_NaN();
}

return detail::fma_imp(x, y, z);
return detail::fma_impl(x, y, z);
}

} // namespace unsafe

} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath

#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FMA_2024_12_17_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,26 @@
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_fabs.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isinf.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isnan.hpp>
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_limits.hpp>

#include <cmath>
#include <type_traits>

namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {

template <typename T>
constexpr auto fpclassify(T x) -> typename std::enable_if<!std::is_integral<T>::value, int>::type
{
if ((boost::multiprecision::backends::cpp_df_qf_detail::ccmath::isnan)(x))
if ((::boost::multiprecision::backends::cpp_df_qf_detail::ccmath::isnan)(x))
{
return FP_NAN;
}
else if ((boost::multiprecision::backends::cpp_df_qf_detail::ccmath::isinf)(x))
else if ((::boost::multiprecision::backends::cpp_df_qf_detail::ccmath::isinf)(x))
{
return FP_INFINITE;
}
else
{
const T fabs_x { boost::multiprecision::backends::cpp_df_qf_detail::ccmath::fabs(x) };
const T fabs_x { ::boost::multiprecision::backends::cpp_df_qf_detail::ccmath::fabs(x) };

if (fabs_x == T(0))
{
Expand Down
Loading

0 comments on commit 37e28bf

Please sign in to comment.