epoc32/include/stdapis/boost/math/special_functions/hypot.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
williamr@2
     1
//  (C) Copyright John Maddock 2005.
williamr@2
     2
//  Use, modification and distribution are subject to the
williamr@2
     3
//  Boost Software License, Version 1.0. (See accompanying file
williamr@2
     4
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     5
williamr@2
     6
#ifndef BOOST_MATH_HYPOT_INCLUDED
williamr@2
     7
#define BOOST_MATH_HYPOT_INCLUDED
williamr@2
     8
williamr@2
     9
#include <cmath>
williamr@2
    10
#include <boost/limits.hpp>
williamr@2
    11
#include <algorithm> // swap
williamr@2
    12
williamr@2
    13
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
williamr@2
    14
#  include <boost/static_assert.hpp>
williamr@2
    15
#else
williamr@2
    16
#  include <boost/assert.hpp>
williamr@2
    17
#endif
williamr@2
    18
williamr@2
    19
#ifdef BOOST_NO_STDC_NAMESPACE
williamr@2
    20
namespace std{ using ::sqrt; using ::fabs; }
williamr@2
    21
#endif
williamr@2
    22
williamr@2
    23
williamr@2
    24
namespace boost{ namespace math{
williamr@2
    25
williamr@2
    26
template <class T>
williamr@2
    27
T hypot(T x, T y)
williamr@2
    28
{
williamr@2
    29
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
williamr@2
    30
   BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized);
williamr@2
    31
#else
williamr@2
    32
   BOOST_ASSERT(std::numeric_limits<T>::is_specialized);
williamr@2
    33
#endif
williamr@2
    34
williamr@2
    35
   //
williamr@2
    36
   // normalize x and y, so that both are positive and x >= y:
williamr@2
    37
   //
williamr@2
    38
   x = (std::fabs)(x);
williamr@2
    39
   y = (std::fabs)(y);
williamr@2
    40
williamr@2
    41
   // special case, see C99 Annex F:
williamr@2
    42
   if(std::numeric_limits<T>::has_infinity
williamr@2
    43
      && ((x == std::numeric_limits<T>::infinity())
williamr@2
    44
      || (y == std::numeric_limits<T>::infinity())))
williamr@2
    45
      return std::numeric_limits<T>::infinity();
williamr@2
    46
williamr@2
    47
   if(y > x) 
williamr@2
    48
      (std::swap)(x, y);
williamr@2
    49
   //
williamr@2
    50
   // figure out overflow and underflow limits:
williamr@2
    51
   //
williamr@2
    52
   T safe_upper = (std::sqrt)((std::numeric_limits<T>::max)()) / 2;
williamr@2
    53
   T safe_lower = (std::sqrt)((std::numeric_limits<T>::min)());
williamr@2
    54
   static const T one = 1;
williamr@2
    55
   //
williamr@2
    56
   // Now handle special cases:
williamr@2
    57
   //
williamr@2
    58
   if(x >= safe_upper)
williamr@2
    59
   {
williamr@2
    60
      if(y <= one)
williamr@2
    61
      {
williamr@2
    62
         // y is neligible:
williamr@2
    63
         return x;
williamr@2
    64
      }
williamr@2
    65
      return (std::sqrt)(x) * (std::sqrt)(y) * (std::sqrt)(x/y + y/x);
williamr@2
    66
   }
williamr@2
    67
   else if(y <= safe_lower)
williamr@2
    68
   {
williamr@2
    69
      if((x >= one) || (y == 0))
williamr@2
    70
      {
williamr@2
    71
         // y is negligible:
williamr@2
    72
         return x;
williamr@2
    73
      }
williamr@2
    74
      return (std::sqrt)(x) * (std::sqrt)(y) * (std::sqrt)(x/y + y/x);
williamr@2
    75
   }
williamr@2
    76
   //
williamr@2
    77
   // If we get here then x^2+y^2 will not overflow or underflow:
williamr@2
    78
   //
williamr@2
    79
   return (std::sqrt)(x*x + y*y);
williamr@2
    80
}
williamr@2
    81
williamr@2
    82
} } // namespaces
williamr@2
    83
williamr@2
    84
#endif // BOOST_MATH_HYPOT_INCLUDED