1 // (C) Copyright John Maddock 2005.
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)
6 #ifndef BOOST_MATH_HYPOT_INCLUDED
7 #define BOOST_MATH_HYPOT_INCLUDED
10 #include <boost/limits.hpp>
11 #include <algorithm> // swap
13 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
14 # include <boost/static_assert.hpp>
16 # include <boost/assert.hpp>
19 #ifdef BOOST_NO_STDC_NAMESPACE
20 namespace std{ using ::sqrt; using ::fabs; }
24 namespace boost{ namespace math{
29 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
30 BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized);
32 BOOST_ASSERT(std::numeric_limits<T>::is_specialized);
36 // normalize x and y, so that both are positive and x >= y:
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 std::numeric_limits<T>::infinity();
50 // figure out overflow and underflow limits:
52 T safe_upper = (std::sqrt)((std::numeric_limits<T>::max)()) / 2;
53 T safe_lower = (std::sqrt)((std::numeric_limits<T>::min)());
54 static const T one = 1;
56 // Now handle special cases:
65 return (std::sqrt)(x) * (std::sqrt)(y) * (std::sqrt)(x/y + y/x);
67 else if(y <= safe_lower)
69 if((x >= one) || (y == 0))
74 return (std::sqrt)(x) * (std::sqrt)(y) * (std::sqrt)(x/y + y/x);
77 // If we get here then x^2+y^2 will not overflow or underflow:
79 return (std::sqrt)(x*x + y*y);
84 #endif // BOOST_MATH_HYPOT_INCLUDED