1 // (C) Copyright John Maddock 2005-2006. 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_HYPOT_INCLUDED 7 #define BOOST_MATH_HYPOT_INCLUDED 8 9 #ifdef _MSC_VER 10 #pragma once 11 #endif 12 13 #include <boost/math/tools/config.hpp> 14 #include <boost/math/tools/precision.hpp> 15 #include <boost/math/policies/error_handling.hpp> 16 #include <boost/math/special_functions/math_fwd.hpp> 17 #include <boost/config/no_tr1/cmath.hpp> 18 #include <algorithm> // for swap 19 20 #ifdef BOOST_NO_STDC_NAMESPACE 21 namespace std{ using ::sqrt; using ::fabs; } 22 #endif 23 24 namespace boost{ namespace math{ namespace detail{ 25 26 template <class T, class Policy> 27 T hypot_imp(T x, T y, const Policy& pol) 28 { 29 // 30 // Normalize x and y, so that both are positive and x >= y: 31 // 32 using std::fabs; using std::sqrt; // ADL of std names 33 34 x = fabs(x); 35 y = fabs(y); 36 37 #ifdef BOOST_MSVC 38 #pragma warning(push) 39 #pragma warning(disable: 4127) 40 #endif 41 // special case, see C99 Annex F: 42 if(std::numeric_limits<T>::has_infinity 43 && ((x == std::numeric_limits<T>::infinity()) 44 || (y == std::numeric_limits<T>::infinity()))) 45 return policies::raise_overflow_error<T>("boost::math::hypot<%1%>(%1%,%1%)", 0, pol); 46 #ifdef BOOST_MSVC 47 #pragma warning(pop) 48 #endif 49 50 if(y > x) 51 (std::swap)(x, y); 52 53 if(x * tools::epsilon<T>() >= y) 54 return x; 55 56 T rat = y / x; 57 return x * sqrt(1 + rat*rat); 58 } // template <class T> T hypot(T x, T y) 59 60 } 61 62 template <class T1, class T2> 63 inline typename tools::promote_args<T1, T2>::type hypot(T1 x,T2 y)64 hypot(T1 x, T2 y) 65 { 66 typedef typename tools::promote_args<T1, T2>::type result_type; 67 return detail::hypot_imp( 68 static_cast<result_type>(x), static_cast<result_type>(y), policies::policy<>()); 69 } 70 71 template <class T1, class T2, class Policy> 72 inline typename tools::promote_args<T1, T2>::type hypot(T1 x,T2 y,const Policy & pol)73 hypot(T1 x, T2 y, const Policy& pol) 74 { 75 typedef typename tools::promote_args<T1, T2>::type result_type; 76 return detail::hypot_imp( 77 static_cast<result_type>(x), static_cast<result_type>(y), pol); 78 } 79 80 } // namespace math 81 } // namespace boost 82 83 #endif // BOOST_MATH_HYPOT_INCLUDED 84 85 86 87