80 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_MODF_HPP7#define BOOST_MATH_CCMATH_MODF_HPP8 9#include <boost/math/ccmath/detail/config.hpp>10 11#ifdef BOOST_MATH_NO_CCMATH12#error "The header <boost/math/modf.hpp> can only be used in C++17 and later."13#endif14 15#include <boost/math/ccmath/abs.hpp>16#include <boost/math/ccmath/isinf.hpp>17#include <boost/math/ccmath/isnan.hpp>18#include <boost/math/ccmath/trunc.hpp>19 20namespace boost::math::ccmath {21 22namespace detail {23 24template <typename Real>25inline constexpr Real modf_error_impl(Real x, Real* iptr)26{27 *iptr = x;28 return boost::math::ccmath::abs(x) == Real(0) ? x :29 x > Real(0) ? Real(0) : -Real(0);30}31 32template <typename Real>33inline constexpr Real modf_nan_impl(Real x, Real* iptr)34{35 *iptr = x;36 return x;37}38 39template <typename Real>40inline constexpr Real modf_impl(Real x, Real* iptr)41{42 *iptr = boost::math::ccmath::trunc(x);43 return (x - *iptr);44}45 46} // Namespace detail47 48template <typename Real>49inline constexpr Real modf(Real x, Real* iptr)50{51 if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))52 {53 return boost::math::ccmath::abs(x) == Real(0) ? detail::modf_error_impl(x, iptr) :54 boost::math::ccmath::isinf(x) ? detail::modf_error_impl(x, iptr) :55 boost::math::ccmath::isnan(x) ? detail::modf_nan_impl(x, iptr) :56 boost::math::ccmath::detail::modf_impl(x, iptr);57 }58 else59 {60 using std::modf;61 return modf(x, iptr);62 }63}64 65inline constexpr float modff(float x, float* iptr)66{67 return boost::math::ccmath::modf(x, iptr);68}69 70#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS71inline constexpr long double modfl(long double x, long double* iptr)72{73 return boost::math::ccmath::modf(x, iptr);74}75#endif76 77} // Namespaces78 79#endif // BOOST_MATH_CCMATH_MODF_HPP80