aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Dos Reis <gdr@merlin.codesourcery.com>2001-11-01 11:00:57 +0000
committerGabriel Dos Reis <gdr@gcc.gnu.org>2001-11-01 11:00:57 +0000
commit3c4e7c50811511bb73db16d2838262e0355020ce (patch)
treef5f15b1cbc246e5f797a5ca59135a14aa87f1ce8
parent9199347f9a503b2a80c9ea2e74763f5d10f040bd (diff)
downloadgcc-3c4e7c50811511bb73db16d2838262e0355020ce.zip
gcc-3c4e7c50811511bb73db16d2838262e0355020ce.tar.gz
gcc-3c4e7c50811511bb73db16d2838262e0355020ce.tar.bz2
std_complex.h (_Norm_helper): New class template.
* include/bits/std_complex.h (_Norm_helper): New class template. (norm): Tweak. From-SVN: r46690
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/include/bits/std_complex.h32
2 files changed, 35 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index bf6780e..cafd3a0 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,8 @@
+2001-11-01 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * include/bits/std_complex.h (_Norm_helper): New class template.
+ (norm): Tweak.
+
2001-10-31 Benjamin Kosnik <bkoz@redhat.com>
libstdc++/4749
diff --git a/libstdc++-v3/include/bits/std_complex.h b/libstdc++-v3/include/bits/std_complex.h
index c9573b7..fcd8c4d 100644
--- a/libstdc++-v3/include/bits/std_complex.h
+++ b/libstdc++-v3/include/bits/std_complex.h
@@ -40,6 +40,7 @@
#pragma GCC system_header
#include <bits/c++config.h>
+#include <bits/cpp_type_traits.h>
#include <bits/std_cmath.h>
#include <bits/std_sstream.h>
@@ -417,12 +418,39 @@ namespace std
arg(const complex<_Tp>& __z)
{ return atan2(__z.imag(), __z.real()); }
+ // 26.2.7/5: norm(__z) returns the squared magintude of __z.
+ // As defined, norm() is -not- a norm is the common mathematical
+ // sens used in numerics. The helper class _Norm_helper<> tries to
+ // distinguish between builtin floating point and the rest, so as
+ // to deliver an answer as close as possible to the real value.
+ template<bool>
+ struct _Norm_helper
+ {
+ template<typename _Tp>
+ static inline _Tp _S_do_it(const complex<_Tp>& __z)
+ {
+ const _Tp __x = __z.real();
+ const _Tp __y = __z.imag();
+ return __x * __x + __y * __y;
+ }
+ };
+
+ template<>
+ struct _Norm_helper<true>
+ {
+ template<typename _Tp>
+ static inline _Tp _S_do_it(const complex<_Tp>& __z)
+ {
+ _Tp __res = abs(__z);
+ return __res * __res;
+ }
+ };
+
template<typename _Tp>
inline _Tp
norm(const complex<_Tp>& __z)
{
- _Tp __res = abs(__z);
- return __res * __res;
+ return _Norm_helper<__is_floating<_Tp>::_M_type>::_S_do_it(__z);
}
template<typename _Tp>