comparison DEPENDENCIES/generic/include/boost/multiprecision/detail/default_ops.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
960 template <class T> 960 template <class T>
961 inline void eval_trunc(T& result, const T& a) 961 inline void eval_trunc(T& result, const T& a)
962 { 962 {
963 BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The trunc function is only valid for floating point types."); 963 BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The trunc function is only valid for floating point types.");
964 int c = eval_fpclassify(a); 964 int c = eval_fpclassify(a);
965 if(c == FP_NAN || c == FP_INFINITE) 965 if(c == (int)FP_NAN || c == (int)FP_INFINITE)
966 { 966 {
967 result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<T>(a), number<T>(a), boost::math::policies::policy<>()).backend(); 967 result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<T>(a), number<T>(a), boost::math::policies::policy<>()).backend();
968 return; 968 return;
969 } 969 }
970 if(eval_get_sign(a) < 0) 970 if(eval_get_sign(a) < 0)
977 inline void eval_round(T& result, const T& a) 977 inline void eval_round(T& result, const T& a)
978 { 978 {
979 BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The round function is only valid for floating point types."); 979 BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The round function is only valid for floating point types.");
980 typedef typename boost::multiprecision::detail::canonical<float, T>::type fp_type; 980 typedef typename boost::multiprecision::detail::canonical<float, T>::type fp_type;
981 int c = eval_fpclassify(a); 981 int c = eval_fpclassify(a);
982 if(c == FP_NAN || c == FP_INFINITE) 982 if((c == (int)FP_NAN) || (c == (int)FP_INFINITE))
983 { 983 {
984 result = boost::math::policies::raise_rounding_error("boost::multiprecision::round<%1%>(%1%)", 0, number<T>(a), number<T>(a), boost::math::policies::policy<>()).backend(); 984 result = boost::math::policies::raise_rounding_error("boost::multiprecision::round<%1%>(%1%)", 0, number<T>(a), number<T>(a), boost::math::policies::policy<>()).backend();
985 return; 985 return;
986 } 986 }
987 if(eval_get_sign(a) < 0) 987 if(eval_get_sign(a) < 0)
1200 typename enable_if_c<sizeof(T) == 0>::type eval_sqrt(); 1200 typename enable_if_c<sizeof(T) == 0>::type eval_sqrt();
1201 template <class T> 1201 template <class T>
1202 typename enable_if_c<sizeof(T) == 0>::type eval_ldexp(); 1202 typename enable_if_c<sizeof(T) == 0>::type eval_ldexp();
1203 template <class T> 1203 template <class T>
1204 typename enable_if_c<sizeof(T) == 0>::type eval_frexp(); 1204 typename enable_if_c<sizeof(T) == 0>::type eval_frexp();
1205
1206 //
1207 // eval_logb and eval_scalbn simply assume base 2 and forward to
1208 // eval_ldexp and eval_frexp:
1209 //
1210 template <class B>
1211 inline typename B::exponent_type eval_ilogb(const B& val)
1212 {
1213 BOOST_STATIC_ASSERT_MSG(!std::numeric_limits<number<B> >::is_specialized || (std::numeric_limits<number<B> >::radix == 2), "The default implementation of ilogb requires a base 2 number type");
1214 typename B::exponent_type e;
1215 B result;
1216 eval_frexp(result, val, &e);
1217 return e - 1;
1218 }
1219 template <class B>
1220 inline void eval_logb(B& result, const B& val)
1221 {
1222 typedef typename boost::mpl::if_c<boost::is_same<boost::intmax_t, long>::value, long long, boost::intmax_t>::type max_t;
1223 result = static_cast<max_t>(eval_ilogb(val));
1224 }
1225 template <class B, class A>
1226 inline void eval_scalbn(B& result, const B& val, A e)
1227 {
1228 BOOST_STATIC_ASSERT_MSG(!std::numeric_limits<number<B> >::is_specialized || (std::numeric_limits<number<B> >::radix == 2), "The default implementation of scalbn requires a base 2 number type");
1229 eval_ldexp(result, val, static_cast<typename B::exponent_type>(e));
1230 }
1205 // 1231 //
1206 // These functions are implemented in separate files, but expanded inline here, 1232 // These functions are implemented in separate files, but expanded inline here,
1207 // DO NOT CHANGE THE ORDER OF THESE INCLUDES: 1233 // DO NOT CHANGE THE ORDER OF THESE INCLUDES:
1208 // 1234 //
1209 #include <boost/multiprecision/detail/functions/constants.hpp> 1235 #include <boost/multiprecision/detail/functions/constants.hpp>
1231 } 1257 }
1232 template <class Backend, multiprecision::expression_template_option ExpressionTemplates> 1258 template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
1233 inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) 1259 inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
1234 { 1260 {
1235 int v = (fpclassify)(arg); 1261 int v = (fpclassify)(arg);
1236 return (v != FP_INFINITE) && (v != FP_NAN); 1262 return (v != (int)FP_INFINITE) && (v != (int)FP_NAN);
1237 } 1263 }
1238 template <class tag, class A1, class A2, class A3, class A4> 1264 template <class tag, class A1, class A2, class A3, class A4>
1239 inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) 1265 inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
1240 { 1266 {
1241 typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type; 1267 typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
1242 return (isfinite)(value_type(arg)); 1268 return (isfinite)(value_type(arg));
1243 } 1269 }
1244 template <class Backend, multiprecision::expression_template_option ExpressionTemplates> 1270 template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
1245 inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) 1271 inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
1246 { 1272 {
1247 return (fpclassify)(arg) == FP_NAN; 1273 return (fpclassify)(arg) == (int)FP_NAN;
1248 } 1274 }
1249 template <class tag, class A1, class A2, class A3, class A4> 1275 template <class tag, class A1, class A2, class A3, class A4>
1250 inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) 1276 inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
1251 { 1277 {
1252 typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type; 1278 typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
1253 return (isnan)(value_type(arg)); 1279 return (isnan)(value_type(arg));
1254 } 1280 }
1255 template <class Backend, multiprecision::expression_template_option ExpressionTemplates> 1281 template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
1256 inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) 1282 inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
1257 { 1283 {
1258 return (fpclassify)(arg) == FP_INFINITE; 1284 return (fpclassify)(arg) == (int)FP_INFINITE;
1259 } 1285 }
1260 template <class tag, class A1, class A2, class A3, class A4> 1286 template <class tag, class A1, class A2, class A3, class A4>
1261 inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) 1287 inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
1262 { 1288 {
1263 typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type; 1289 typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
1264 return (isinf)(value_type(arg)); 1290 return (isinf)(value_type(arg));
1265 } 1291 }
1266 template <class Backend, multiprecision::expression_template_option ExpressionTemplates> 1292 template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
1267 inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg) 1293 inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
1268 { 1294 {
1269 return (fpclassify)(arg) == FP_NORMAL; 1295 return (fpclassify)(arg) == (int)FP_NORMAL;
1270 } 1296 }
1271 template <class tag, class A1, class A2, class A3, class A4> 1297 template <class tag, class A1, class A2, class A3, class A4>
1272 inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg) 1298 inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
1273 { 1299 {
1274 typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type; 1300 typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
1533 inline long long llround(const number<T, ExpressionTemplates>& v) 1559 inline long long llround(const number<T, ExpressionTemplates>& v)
1534 { 1560 {
1535 return llround(v, boost::math::policies::policy<>()); 1561 return llround(v, boost::math::policies::policy<>());
1536 } 1562 }
1537 #endif 1563 #endif
1564 //
1565 // frexp does not return an expression template since we require the
1566 // integer argument to be evaluated even if the returned value is
1567 // not assigned to anything...
1568 //
1569 template <class T, expression_template_option ExpressionTemplates>
1570 inline typename enable_if_c<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, short* pint)
1571 {
1572 using default_ops::eval_frexp;
1573 number<T, ExpressionTemplates> result;
1574 eval_frexp(result.backend(), v.backend(), pint);
1575 return BOOST_MP_MOVE(result);
1576 }
1577 template <class tag, class A1, class A2, class A3, class A4>
1578 inline typename enable_if_c<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type
1579 frexp(const detail::expression<tag, A1, A2, A3, A4>& v, short* pint)
1580 {
1581 typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
1582 return BOOST_MP_MOVE(frexp(static_cast<number_type>(v), pint));
1583 }
1584 template <class T, expression_template_option ExpressionTemplates>
1585 inline typename enable_if_c<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, int* pint)
1586 {
1587 using default_ops::eval_frexp;
1588 number<T, ExpressionTemplates> result;
1589 eval_frexp(result.backend(), v.backend(), pint);
1590 return BOOST_MP_MOVE(result);
1591 }
1592 template <class tag, class A1, class A2, class A3, class A4>
1593 inline typename enable_if_c<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type
1594 frexp(const detail::expression<tag, A1, A2, A3, A4>& v, int* pint)
1595 {
1596 typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
1597 return BOOST_MP_MOVE(frexp(static_cast<number_type>(v), pint));
1598 }
1599 template <class T, expression_template_option ExpressionTemplates>
1600 inline typename enable_if_c<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, long* pint)
1601 {
1602 using default_ops::eval_frexp;
1603 number<T, ExpressionTemplates> result;
1604 eval_frexp(result.backend(), v.backend(), pint);
1605 return BOOST_MP_MOVE(result);
1606 }
1607 template <class tag, class A1, class A2, class A3, class A4>
1608 inline typename enable_if_c<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type
1609 frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long* pint)
1610 {
1611 typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
1612 return BOOST_MP_MOVE(frexp(static_cast<number_type>(v), pint));
1613 }
1614 template <class T, expression_template_option ExpressionTemplates>
1615 inline typename enable_if_c<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, long long* pint)
1616 {
1617 using default_ops::eval_frexp;
1618 number<T, ExpressionTemplates> result;
1619 eval_frexp(result.backend(), v.backend(), pint);
1620 return BOOST_MP_MOVE(result);
1621 }
1622 template <class tag, class A1, class A2, class A3, class A4>
1623 inline typename enable_if_c<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type
1624 frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long long* pint)
1625 {
1626 typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
1627 return BOOST_MP_MOVE(frexp(static_cast<number_type>(v), pint));
1628 }
1538 1629
1539 template <class B, expression_template_option ExpressionTemplates> 1630 template <class B, expression_template_option ExpressionTemplates>
1540 inline typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, ExpressionTemplates> >::type 1631 inline typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, ExpressionTemplates> >::type
1541 sqrt(const number<B, ExpressionTemplates>& x) 1632 sqrt(const number<B, ExpressionTemplates>& x)
1542 { 1633 {
2005 UNARY_OP_FUNCTOR(atan, number_kind_floating_point) 2096 UNARY_OP_FUNCTOR(atan, number_kind_floating_point)
2006 UNARY_OP_FUNCTOR(cosh, number_kind_floating_point) 2097 UNARY_OP_FUNCTOR(cosh, number_kind_floating_point)
2007 UNARY_OP_FUNCTOR(sinh, number_kind_floating_point) 2098 UNARY_OP_FUNCTOR(sinh, number_kind_floating_point)
2008 UNARY_OP_FUNCTOR(tanh, number_kind_floating_point) 2099 UNARY_OP_FUNCTOR(tanh, number_kind_floating_point)
2009 2100
2010 HETERO_BINARY_OP_FUNCTOR(ldexp, int, number_kind_floating_point) 2101 HETERO_BINARY_OP_FUNCTOR(ldexp, short, number_kind_floating_point)
2011 HETERO_BINARY_OP_FUNCTOR(frexp, int*, number_kind_floating_point) 2102 //HETERO_BINARY_OP_FUNCTOR(frexp, short*, number_kind_floating_point)
2103 HETERO_BINARY_OP_FUNCTOR_B(ldexp, int, number_kind_floating_point)
2104 //HETERO_BINARY_OP_FUNCTOR_B(frexp, int*, number_kind_floating_point)
2012 HETERO_BINARY_OP_FUNCTOR_B(ldexp, long, number_kind_floating_point) 2105 HETERO_BINARY_OP_FUNCTOR_B(ldexp, long, number_kind_floating_point)
2013 HETERO_BINARY_OP_FUNCTOR_B(frexp, long*, number_kind_floating_point) 2106 //HETERO_BINARY_OP_FUNCTOR_B(frexp, long*, number_kind_floating_point)
2014 HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long, number_kind_floating_point) 2107 HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long, number_kind_floating_point)
2015 HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*, number_kind_floating_point) 2108 //HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*, number_kind_floating_point)
2016 BINARY_OP_FUNCTOR(pow, number_kind_floating_point) 2109 BINARY_OP_FUNCTOR(pow, number_kind_floating_point)
2017 BINARY_OP_FUNCTOR(fmod, number_kind_floating_point) 2110 BINARY_OP_FUNCTOR(fmod, number_kind_floating_point)
2018 BINARY_OP_FUNCTOR(atan2, number_kind_floating_point) 2111 BINARY_OP_FUNCTOR(atan2, number_kind_floating_point)
2019 2112
2113 UNARY_OP_FUNCTOR(logb, number_kind_floating_point)
2114 HETERO_BINARY_OP_FUNCTOR(scalbn, short, number_kind_floating_point)
2115 HETERO_BINARY_OP_FUNCTOR_B(scalbn, int, number_kind_floating_point)
2116 HETERO_BINARY_OP_FUNCTOR_B(scalbn, long, number_kind_floating_point)
2117 HETERO_BINARY_OP_FUNCTOR_B(scalbn, long long, number_kind_floating_point)
2118
2020 // 2119 //
2021 // Integer functions: 2120 // Integer functions:
2022 // 2121 //
2023 BINARY_OP_FUNCTOR(gcd, number_kind_integer) 2122 BINARY_OP_FUNCTOR(gcd, number_kind_integer)
2024 BINARY_OP_FUNCTOR(lcm, number_kind_integer) 2123 BINARY_OP_FUNCTOR(lcm, number_kind_integer)
2025 HETERO_BINARY_OP_FUNCTOR_B(pow, unsigned, number_kind_integer) 2124 HETERO_BINARY_OP_FUNCTOR_B(pow, unsigned, number_kind_integer)
2026 2125
2027 #undef BINARY_OP_FUNCTOR 2126 #undef BINARY_OP_FUNCTOR
2028 #undef UNARY_OP_FUNCTOR 2127 #undef UNARY_OP_FUNCTOR
2128
2129 //
2130 // ilogb:
2131 //
2132 template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
2133 inline typename enable_if_c<number_category<Backend>::value == number_kind_floating_point, typename Backend::exponent_type>::type
2134 ilogb(const multiprecision::number<Backend, ExpressionTemplates>& val)
2135 {
2136 using default_ops::eval_ilogb;
2137 return eval_ilogb(val.backend());
2138 }
2139
2140 template <class tag, class A1, class A2, class A3, class A4>
2141 inline typename enable_if_c<number_category<detail::expression<tag, A1, A2, A3, A4> >::value == number_kind_floating_point, typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type::backend_type::exponent_type>::type
2142 ilogb(const detail::expression<tag, A1, A2, A3, A4>& val)
2143 {
2144 using default_ops::eval_ilogb;
2145 typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type arg(val);
2146 return eval_ilogb(arg.backend());
2147 }
2029 2148
2030 } //namespace multiprecision 2149 } //namespace multiprecision
2031 2150
2032 namespace math{ 2151 namespace math{
2033 // 2152 //