]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright John Maddock 2007. |
2 | // Use, modification and distribution are subject to the | |
3 | // Boost Software License, Version 1.0. (See accompanying file | |
4 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #ifndef BOOST_MATH_TRUNC_HPP | |
7 | #define BOOST_MATH_TRUNC_HPP | |
8 | ||
9 | #ifdef _MSC_VER | |
10 | #pragma once | |
11 | #endif | |
12 | ||
13 | #include <boost/math/special_functions/math_fwd.hpp> | |
14 | #include <boost/math/tools/config.hpp> | |
15 | #include <boost/math/policies/error_handling.hpp> | |
16 | #include <boost/math/special_functions/fpclassify.hpp> | |
17 | ||
18 | namespace boost{ namespace math{ namespace detail{ | |
19 | ||
20 | template <class T, class Policy> | |
21 | inline typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol, const mpl::false_&) | |
22 | { | |
23 | BOOST_MATH_STD_USING | |
24 | typedef typename tools::promote_args<T>::type result_type; | |
25 | if(!(boost::math::isfinite)(v)) | |
26 | return policies::raise_rounding_error("boost::math::trunc<%1%>(%1%)", 0, static_cast<result_type>(v), static_cast<result_type>(v), pol); | |
27 | return (v >= 0) ? static_cast<result_type>(floor(v)) : static_cast<result_type>(ceil(v)); | |
28 | } | |
29 | ||
30 | template <class T, class Policy> | |
31 | inline typename tools::promote_args<T>::type trunc(const T& v, const Policy&, const mpl::true_&) | |
32 | { | |
33 | return v; | |
34 | } | |
35 | ||
36 | } | |
37 | ||
38 | template <class T, class Policy> | |
39 | inline typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol) | |
40 | { | |
41 | return detail::trunc(v, pol, mpl::bool_<detail::is_integer_for_rounding<T>::value>()); | |
42 | } | |
43 | template <class T> | |
44 | inline typename tools::promote_args<T>::type trunc(const T& v) | |
45 | { | |
46 | return trunc(v, policies::policy<>()); | |
47 | } | |
48 | // | |
49 | // The following functions will not compile unless T has an | |
50 | // implicit convertion to the integer types. For user-defined | |
51 | // number types this will likely not be the case. In that case | |
52 | // these functions should either be specialized for the UDT in | |
53 | // question, or else overloads should be placed in the same | |
54 | // namespace as the UDT: these will then be found via argument | |
55 | // dependent lookup. See our concept archetypes for examples. | |
56 | // | |
57 | template <class T, class Policy> | |
58 | inline int itrunc(const T& v, const Policy& pol) | |
59 | { | |
60 | BOOST_MATH_STD_USING | |
61 | typedef typename tools::promote_args<T>::type result_type; | |
62 | result_type r = boost::math::trunc(v, pol); | |
63 | if((r > (std::numeric_limits<int>::max)()) || (r < (std::numeric_limits<int>::min)())) | |
64 | return static_cast<int>(policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, static_cast<result_type>(v), 0, pol)); | |
65 | return static_cast<int>(r); | |
66 | } | |
67 | template <class T> | |
68 | inline int itrunc(const T& v) | |
69 | { | |
70 | return itrunc(v, policies::policy<>()); | |
71 | } | |
72 | ||
73 | template <class T, class Policy> | |
74 | inline long ltrunc(const T& v, const Policy& pol) | |
75 | { | |
76 | BOOST_MATH_STD_USING | |
77 | typedef typename tools::promote_args<T>::type result_type; | |
78 | result_type r = boost::math::trunc(v, pol); | |
79 | if((r > (std::numeric_limits<long>::max)()) || (r < (std::numeric_limits<long>::min)())) | |
80 | return static_cast<long>(policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, static_cast<result_type>(v), 0L, pol)); | |
81 | return static_cast<long>(r); | |
82 | } | |
83 | template <class T> | |
84 | inline long ltrunc(const T& v) | |
85 | { | |
86 | return ltrunc(v, policies::policy<>()); | |
87 | } | |
88 | ||
89 | #ifdef BOOST_HAS_LONG_LONG | |
90 | ||
91 | template <class T, class Policy> | |
92 | inline boost::long_long_type lltrunc(const T& v, const Policy& pol) | |
93 | { | |
94 | BOOST_MATH_STD_USING | |
95 | typedef typename tools::promote_args<T>::type result_type; | |
96 | result_type r = boost::math::trunc(v, pol); | |
97 | if((r > (std::numeric_limits<boost::long_long_type>::max)()) || (r < (std::numeric_limits<boost::long_long_type>::min)())) | |
98 | return static_cast<boost::long_long_type>(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, static_cast<boost::long_long_type>(0), pol)); | |
99 | return static_cast<boost::long_long_type>(r); | |
100 | } | |
101 | template <class T> | |
102 | inline boost::long_long_type lltrunc(const T& v) | |
103 | { | |
104 | return lltrunc(v, policies::policy<>()); | |
105 | } | |
106 | ||
107 | #endif | |
108 | ||
109 | }} // namespaces | |
110 | ||
111 | #endif // BOOST_MATH_TRUNC_HPP |