Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:36:24

0001 //  Copyright John Maddock 2007.
0002 //  Copyright Matt Borland 2023.
0003 //  Use, modification and distribution are subject to the
0004 //  Boost Software License, Version 1.0. (See accompanying file
0005 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_MATH_TRUNC_HPP
0008 #define BOOST_MATH_TRUNC_HPP
0009 
0010 #ifdef _MSC_VER
0011 #pragma once
0012 #endif
0013 
0014 #include <boost/math/tools/config.hpp>
0015 #include <boost/math/tools/type_traits.hpp>
0016 #include <boost/math/tools/numeric_limits.hpp>
0017 
0018 #ifndef BOOST_MATH_HAS_NVRTC
0019 
0020 #include <type_traits>
0021 #include <boost/math/special_functions/math_fwd.hpp>
0022 #include <boost/math/ccmath/detail/config.hpp>
0023 #include <boost/math/policies/error_handling.hpp>
0024 #include <boost/math/special_functions/fpclassify.hpp>
0025 #include <boost/math/tools/is_constant_evaluated.hpp>
0026 
0027 #if !defined(BOOST_MATH_NO_CCMATH) && !defined(BOOST_MATH_NO_CONSTEXPR_DETECTION)
0028 #include <boost/math/ccmath/ldexp.hpp>
0029 #    define BOOST_MATH_HAS_CONSTEXPR_LDEXP
0030 #endif
0031 
0032 namespace boost{ namespace math{ namespace detail{
0033 
0034 template <class T, class Policy>
0035 BOOST_MATH_GPU_ENABLED inline tools::promote_args_t<T> trunc(const T& v, const Policy& pol, const std::false_type&)
0036 {
0037    BOOST_MATH_STD_USING
0038    using result_type = tools::promote_args_t<T>;
0039    if(!(boost::math::isfinite)(v))
0040    {
0041       return policies::raise_rounding_error("boost::math::trunc<%1%>(%1%)", nullptr, static_cast<result_type>(v), static_cast<result_type>(v), pol);
0042    }
0043    return (v >= 0) ? static_cast<result_type>(floor(v)) : static_cast<result_type>(ceil(v));
0044 }
0045 
0046 template <class T, class Policy>
0047 BOOST_MATH_GPU_ENABLED inline tools::promote_args_t<T> trunc(const T& v, const Policy&, const std::true_type&)
0048 {
0049    return v;
0050 }
0051 
0052 } // Namespace detail
0053 
0054 template <class T, class Policy>
0055 BOOST_MATH_GPU_ENABLED inline tools::promote_args_t<T> trunc(const T& v, const Policy& pol)
0056 {
0057    return detail::trunc(v, pol, std::integral_constant<bool, detail::is_integer_for_rounding<T>::value>());
0058 }
0059 
0060 template <class T>
0061 BOOST_MATH_GPU_ENABLED inline tools::promote_args_t<T> trunc(const T& v)
0062 {
0063    return trunc(v, policies::policy<>());
0064 }
0065 
0066 #else // Special handling for nvrtc
0067 
0068 namespace boost {
0069 namespace math {
0070 
0071 namespace detail {
0072 
0073 template <typename T>
0074 BOOST_MATH_GPU_ENABLED double trunc_impl(T x)
0075 {
0076    return static_cast<double>(x);
0077 }
0078 
0079 BOOST_MATH_GPU_ENABLED inline float trunc_impl(float x)
0080 {
0081    return ::truncf(x);
0082 }
0083 
0084 BOOST_MATH_GPU_ENABLED inline double trunc_impl(double x)
0085 {
0086    return ::trunc(x);
0087 }
0088 
0089 } // Namespace detail
0090 
0091 template <typename T, typename Policy>
0092 BOOST_MATH_GPU_ENABLED auto trunc(T x, const Policy&)
0093 {
0094    return detail::trunc_impl(x);
0095 }
0096 
0097 template <typename T>
0098 BOOST_MATH_GPU_ENABLED auto trunc(T x)
0099 {
0100    return detail::trunc_impl(x);
0101 }
0102 
0103 #endif
0104 
0105 #ifndef BOOST_MATH_HAS_NVRTC
0106 
0107 //
0108 // The following functions will not compile unless T has an
0109 // implicit conversion to the integer types.  For user-defined
0110 // number types this will likely not be the case.  In that case
0111 // these functions should either be specialized for the UDT in
0112 // question, or else overloads should be placed in the same
0113 // namespace as the UDT: these will then be found via argument
0114 // dependent lookup.  See our concept archetypes for examples.
0115 //
0116 // Non-standard numeric limits syntax "(std::numeric_limits<int>::max)()"
0117 // is to avoid macro substiution from MSVC
0118 // https://stackoverflow.com/questions/27442885/syntax-error-with-stdnumeric-limitsmax
0119 //
0120 template <class T, class Policy>
0121 BOOST_MATH_GPU_ENABLED inline int itrunc(const T& v, const Policy& pol)
0122 {
0123    BOOST_MATH_STD_USING
0124    using result_type = tools::promote_args_t<T>;
0125    result_type r = boost::math::trunc(v, pol);
0126 
0127    #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT)
0128    if constexpr (std::is_arithmetic_v<result_type>
0129                  #ifdef BOOST_MATH_FLOAT128_TYPE
0130                  && !std::is_same_v<BOOST_MATH_FLOAT128_TYPE, result_type>
0131                  #endif
0132                 )
0133    {
0134       constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast<result_type>(1), std::numeric_limits<int>::digits);
0135       
0136       if (r >= max_val || r < -max_val)
0137       {
0138          return static_cast<int>(boost::math::policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", nullptr, v, static_cast<int>(0), pol));
0139       }
0140    }
0141    else
0142    {
0143       static const result_type max_val = ldexp(static_cast<result_type>(1), std::numeric_limits<int>::digits);
0144    
0145       if (r >= max_val || r < -max_val)
0146       {
0147          return static_cast<int>(boost::math::policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", nullptr, v, static_cast<int>(0), pol));
0148       }
0149    }
0150    #else
0151    BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast<result_type>(1), std::numeric_limits<int>::digits);
0152 
0153    if (r >= max_val || r < -max_val)
0154    {
0155       return static_cast<int>(boost::math::policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", nullptr, v, static_cast<int>(0), pol));
0156    }
0157    #endif
0158 
0159    return static_cast<int>(r);
0160 }
0161 
0162 template <class T>
0163 BOOST_MATH_GPU_ENABLED inline int itrunc(const T& v)
0164 {
0165    return itrunc(v, policies::policy<>());
0166 }
0167 
0168 template <class T, class Policy>
0169 BOOST_MATH_GPU_ENABLED inline long ltrunc(const T& v, const Policy& pol)
0170 {
0171    BOOST_MATH_STD_USING
0172    using result_type = tools::promote_args_t<T>;
0173    result_type r = boost::math::trunc(v, pol);
0174 
0175    #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT)
0176    if constexpr (std::is_arithmetic_v<result_type>
0177                  #ifdef BOOST_MATH_FLOAT128_TYPE
0178                  && !std::is_same_v<BOOST_MATH_FLOAT128_TYPE, result_type>
0179                  #endif
0180                 )
0181    {
0182       constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast<result_type>(1), std::numeric_limits<long>::digits);
0183       
0184       if (r >= max_val || r < -max_val)
0185       {
0186          return static_cast<long>(boost::math::policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", nullptr, v, static_cast<long>(0), pol));
0187       }
0188    }
0189    else
0190    {
0191       static const result_type max_val = ldexp(static_cast<result_type>(1), std::numeric_limits<long>::digits);
0192    
0193       if (r >= max_val || r < -max_val)
0194       {
0195          return static_cast<long>(boost::math::policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", nullptr, v, static_cast<long>(0), pol));
0196       }
0197    }
0198    #else
0199    BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast<result_type>(1), std::numeric_limits<long>::digits);
0200 
0201    if (r >= max_val || r < -max_val)
0202    {
0203       return static_cast<long>(boost::math::policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", nullptr, v, static_cast<long>(0), pol));
0204    }
0205    #endif
0206 
0207    return static_cast<long>(r);
0208 }
0209 
0210 template <class T>
0211 BOOST_MATH_GPU_ENABLED inline long ltrunc(const T& v)
0212 {
0213    return ltrunc(v, policies::policy<>());
0214 }
0215 
0216 template <class T, class Policy>
0217 BOOST_MATH_GPU_ENABLED inline long long lltrunc(const T& v, const Policy& pol)
0218 {
0219    BOOST_MATH_STD_USING
0220    using result_type = tools::promote_args_t<T>;
0221    result_type r = boost::math::trunc(v, pol);
0222 
0223    #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT)
0224    if constexpr (std::is_arithmetic_v<result_type>
0225                  #ifdef BOOST_MATH_FLOAT128_TYPE
0226                  && !std::is_same_v<BOOST_MATH_FLOAT128_TYPE, result_type>
0227                  #endif
0228                 )
0229    {
0230       constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast<result_type>(1), std::numeric_limits<long long>::digits);
0231       
0232       if (r >= max_val || r < -max_val)
0233       {
0234          return static_cast<long long>(boost::math::policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", nullptr, v, static_cast<long long>(0), pol));
0235       }
0236    }
0237    else
0238    {
0239       static const result_type max_val = ldexp(static_cast<result_type>(1), std::numeric_limits<long long>::digits);
0240    
0241       if (r >= max_val || r < -max_val)
0242       {
0243          return static_cast<long long>(boost::math::policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", nullptr, v, static_cast<long long>(0), pol));
0244       }
0245    }
0246    #else
0247    BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast<result_type>(1), std::numeric_limits<long long>::digits);
0248 
0249    if (r >= max_val || r < -max_val)
0250    {
0251       return static_cast<long long>(boost::math::policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", nullptr, v, static_cast<long long>(0), pol));
0252    }
0253    #endif
0254 
0255    return static_cast<long long>(r);
0256 }
0257 
0258 template <class T>
0259 BOOST_MATH_GPU_ENABLED inline long long lltrunc(const T& v)
0260 {
0261    return lltrunc(v, policies::policy<>());
0262 }
0263 
0264 #else // Reduced impl specifically for NVRTC platform
0265 
0266 namespace detail {
0267 
0268 template <typename TargetType, typename T>
0269 BOOST_MATH_GPU_ENABLED TargetType integer_trunc_impl(T v)
0270 {
0271    double r = boost::math::trunc(v);
0272 
0273    const double max_val = ldexp(1.0, boost::math::numeric_limits<TargetType>::digits);
0274 
0275    if (r >= max_val || r < -max_val)
0276    {
0277       r = 0;
0278    }
0279 
0280    return static_cast<TargetType>(r);
0281 }
0282 
0283 } // Namespace detail
0284 
0285 template <typename T>
0286 BOOST_MATH_GPU_ENABLED int itrunc(T v)
0287 {
0288    return detail::integer_trunc_impl<int>(v);
0289 }
0290 
0291 template <typename T, typename Policy>
0292 BOOST_MATH_GPU_ENABLED int itrunc(T v, const Policy&)
0293 {
0294    return detail::integer_trunc_impl<int>(v);
0295 }
0296 
0297 template <typename T>
0298 BOOST_MATH_GPU_ENABLED long ltrunc(T v)
0299 {
0300    return detail::integer_trunc_impl<long>(v);
0301 }
0302 
0303 template <typename T, typename Policy>
0304 BOOST_MATH_GPU_ENABLED long ltrunc(T v, const Policy&)
0305 {
0306    return detail::integer_trunc_impl<long>(v);
0307 }
0308 
0309 template <typename T>
0310 BOOST_MATH_GPU_ENABLED long long lltrunc(T v)
0311 {
0312    return detail::integer_trunc_impl<long long>(v);
0313 }
0314 
0315 template <typename T, typename Policy>
0316 BOOST_MATH_GPU_ENABLED long long lltrunc(T v, const Policy&)
0317 {
0318    return detail::integer_trunc_impl<long long>(v);
0319 }
0320 
0321 #endif // BOOST_MATH_HAS_NVRTC
0322 
0323 template <class T, class Policy>
0324 BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t<boost::math::is_constructible_v<int, T>, int>
0325    iconvert(const T& v, const Policy&)
0326 {
0327    return static_cast<int>(v);
0328 }
0329 
0330 template <class T, class Policy>
0331 BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t<!boost::math::is_constructible_v<int, T>, int>
0332    iconvert(const T& v, const Policy& pol)
0333 {
0334    using boost::math::itrunc;
0335    return itrunc(v, pol);
0336 }
0337 
0338 template <class T, class Policy>
0339 BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t<boost::math::is_constructible_v<long, T>, long>
0340    lconvert(const T& v, const Policy&)
0341 {
0342    return static_cast<long>(v);
0343 }
0344 
0345 template <class T, class Policy>
0346 BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t<!boost::math::is_constructible_v<long, T>, long>
0347    lconvert(const T& v, const Policy& pol)
0348 {
0349    using boost::math::ltrunc;
0350    return ltrunc(v, pol);
0351 }
0352 
0353 template <class T, class Policy>
0354 BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t<boost::math::is_constructible_v<long long, T>, long long>
0355    llconvert(const T& v, const Policy&)
0356 {
0357    return static_cast<long long>(v);
0358 }
0359 
0360 template <class T, class Policy>
0361 BOOST_MATH_GPU_ENABLED inline typename boost::math::enable_if_t<!boost::math::is_constructible_v<long long, T>, long long>
0362    llconvert(const T& v, const Policy& pol)
0363 {
0364    using boost::math::lltrunc;
0365    return lltrunc(v, pol);
0366 }
0367 
0368 template <class T, class Policy>
0369 BOOST_MATH_GPU_ENABLED [[deprecated("Use llconvert")]] inline boost::math::enable_if_t<boost::math::is_constructible_v<long long, T>, long long>
0370    llconvertert(const T& v, const Policy&)
0371 {
0372    return static_cast<long long>(v);
0373 }
0374 
0375 template <class T, class Policy>
0376 BOOST_MATH_GPU_ENABLED [[deprecated("Use llconvert")]] inline typename boost::math::enable_if_t<!boost::math::is_constructible_v<long long, T>, long long>
0377    llconvertert(const T& v, const Policy& pol)
0378 {
0379    using boost::math::lltrunc;
0380    return lltrunc(v, pol);
0381 }
0382 
0383 }} // namespaces
0384 
0385 #endif // BOOST_MATH_TRUNC_HPP