epoc32/include/stdapis/boost/math/special_functions/hypot.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     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)
     5 
     6 #ifndef BOOST_MATH_HYPOT_INCLUDED
     7 #define BOOST_MATH_HYPOT_INCLUDED
     8 
     9 #include <cmath>
    10 #include <boost/limits.hpp>
    11 #include <algorithm> // swap
    12 
    13 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
    14 #  include <boost/static_assert.hpp>
    15 #else
    16 #  include <boost/assert.hpp>
    17 #endif
    18 
    19 #ifdef BOOST_NO_STDC_NAMESPACE
    20 namespace std{ using ::sqrt; using ::fabs; }
    21 #endif
    22 
    23 
    24 namespace boost{ namespace math{
    25 
    26 template <class T>
    27 T hypot(T x, T y)
    28 {
    29 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
    30    BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized);
    31 #else
    32    BOOST_ASSERT(std::numeric_limits<T>::is_specialized);
    33 #endif
    34 
    35    //
    36    // normalize x and y, so that both are positive and x >= y:
    37    //
    38    x = (std::fabs)(x);
    39    y = (std::fabs)(y);
    40 
    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();
    46 
    47    if(y > x) 
    48       (std::swap)(x, y);
    49    //
    50    // figure out overflow and underflow limits:
    51    //
    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;
    55    //
    56    // Now handle special cases:
    57    //
    58    if(x >= safe_upper)
    59    {
    60       if(y <= one)
    61       {
    62          // y is neligible:
    63          return x;
    64       }
    65       return (std::sqrt)(x) * (std::sqrt)(y) * (std::sqrt)(x/y + y/x);
    66    }
    67    else if(y <= safe_lower)
    68    {
    69       if((x >= one) || (y == 0))
    70       {
    71          // y is negligible:
    72          return x;
    73       }
    74       return (std::sqrt)(x) * (std::sqrt)(y) * (std::sqrt)(x/y + y/x);
    75    }
    76    //
    77    // If we get here then x^2+y^2 will not overflow or underflow:
    78    //
    79    return (std::sqrt)(x*x + y*y);
    80 }
    81 
    82 } } // namespaces
    83 
    84 #endif // BOOST_MATH_HYPOT_INCLUDED