|
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_COMPLEX_DETAILS_INCLUDED |
|
7 #define BOOST_MATH_COMPLEX_DETAILS_INCLUDED |
|
8 // |
|
9 // This header contains all the support code that is common to the |
|
10 // inverse trig complex functions, it also contains all the includes |
|
11 // that we need to implement all these functions. |
|
12 // |
|
13 #include <boost/detail/workaround.hpp> |
|
14 #include <boost/config.hpp> |
|
15 #include <boost/config/no_tr1/complex.hpp> |
|
16 #include <boost/limits.hpp> |
|
17 #include <math.h> // isnan where available |
|
18 #include <cmath> |
|
19 |
|
20 #ifdef BOOST_NO_STDC_NAMESPACE |
|
21 namespace std{ using ::sqrt; } |
|
22 #endif |
|
23 |
|
24 namespace boost{ namespace math{ namespace detail{ |
|
25 |
|
26 template <class T> |
|
27 inline bool test_is_nan(T t) |
|
28 { |
|
29 // Comparisons with Nan's always fail: |
|
30 return std::numeric_limits<T>::has_infinity && (!(t <= std::numeric_limits<T>::infinity()) || !(t >= -std::numeric_limits<T>::infinity())); |
|
31 } |
|
32 #ifdef isnan |
|
33 template<> inline bool test_is_nan<float>(float t) { return isnan(t); } |
|
34 template<> inline bool test_is_nan<double>(double t) { return isnan(t); } |
|
35 template<> inline bool test_is_nan<long double>(long double t) { return isnan(t); } |
|
36 #endif |
|
37 |
|
38 template <class T> |
|
39 inline T mult_minus_one(const T& t) |
|
40 { |
|
41 return test_is_nan(t) ? t : -t; |
|
42 } |
|
43 |
|
44 template <class T> |
|
45 inline std::complex<T> mult_i(const std::complex<T>& t) |
|
46 { |
|
47 return std::complex<T>(mult_minus_one(t.imag()), t.real()); |
|
48 } |
|
49 |
|
50 template <class T> |
|
51 inline std::complex<T> mult_minus_i(const std::complex<T>& t) |
|
52 { |
|
53 return std::complex<T>(t.imag(), mult_minus_one(t.real())); |
|
54 } |
|
55 |
|
56 template <class T> |
|
57 inline T safe_max(T t) |
|
58 { |
|
59 return std::sqrt((std::numeric_limits<T>::max)()) / t; |
|
60 } |
|
61 inline long double safe_max(long double t) |
|
62 { |
|
63 // long double sqrt often returns infinity due to |
|
64 // insufficient internal precision: |
|
65 return std::sqrt((std::numeric_limits<double>::max)()) / t; |
|
66 } |
|
67 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
|
68 // workaround for type deduction bug: |
|
69 inline float safe_max(float t) |
|
70 { |
|
71 return std::sqrt((std::numeric_limits<float>::max)()) / t; |
|
72 } |
|
73 inline double safe_max(double t) |
|
74 { |
|
75 return std::sqrt((std::numeric_limits<double>::max)()) / t; |
|
76 } |
|
77 #endif |
|
78 template <class T> |
|
79 inline T safe_min(T t) |
|
80 { |
|
81 return std::sqrt((std::numeric_limits<T>::min)()) * t; |
|
82 } |
|
83 inline long double safe_min(long double t) |
|
84 { |
|
85 // long double sqrt often returns zero due to |
|
86 // insufficient internal precision: |
|
87 return std::sqrt((std::numeric_limits<double>::min)()) * t; |
|
88 } |
|
89 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
|
90 // type deduction workaround: |
|
91 inline double safe_min(double t) |
|
92 { |
|
93 return std::sqrt((std::numeric_limits<double>::min)()) * t; |
|
94 } |
|
95 inline float safe_min(float t) |
|
96 { |
|
97 return std::sqrt((std::numeric_limits<float>::min)()) * t; |
|
98 } |
|
99 #endif |
|
100 |
|
101 } } } // namespaces |
|
102 |
|
103 #endif // BOOST_MATH_COMPLEX_DETAILS_INCLUDED |
|
104 |