summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-02 18:43:26 +0000
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-02 18:43:26 +0000
commitc1aeb0ddd9dafdaba9a74ada8358eff863b1dfce (patch)
treed7679da43ffa3636ae8f3dcfa7dc84d9a971e9f2
parent609cab98a1445d1297053e842d0799dbe02e532c (diff)
downloadgcc-c1aeb0ddd9dafdaba9a74ada8358eff863b1dfce.tar.gz
2011-11-02 Richard B. Kreckel <kreckel@ginac.de>
Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/50880 * include/std/complex (__complex_acosh): Fix in a better way, use Kahan's formula. * include/tr1/complex (__complex_acosh): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180787 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/include/std/complex11
-rw-r--r--libstdc++-v3/include/tr1/complex11
2 files changed, 6 insertions, 16 deletions
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index 3c41b483cd2..d7423433803 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -1686,14 +1686,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::complex<_Tp>
__complex_acosh(const std::complex<_Tp>& __z)
{
- std::complex<_Tp> __t((__z.real() - __z.imag())
- * (__z.real() + __z.imag()) - _Tp(1.0),
- _Tp(2.0) * __z.real() * __z.imag());
- __t = std::sqrt(__t);
- if (__z.real() < _Tp())
- __t = -__t;
-
- return std::log(__t + __z);
+ // Kahan's formula.
+ return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0)))
+ + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0))));
}
#if _GLIBCXX_USE_C99_COMPLEX_TR1
diff --git a/libstdc++-v3/include/tr1/complex b/libstdc++-v3/include/tr1/complex
index d831eeb0146..689ea167ba2 100644
--- a/libstdc++-v3/include/tr1/complex
+++ b/libstdc++-v3/include/tr1/complex
@@ -185,14 +185,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::complex<_Tp>
__complex_acosh(const std::complex<_Tp>& __z)
{
- std::complex<_Tp> __t((__z.real() - __z.imag())
- * (__z.real() + __z.imag()) - _Tp(1.0),
- _Tp(2.0) * __z.real() * __z.imag());
- __t = std::sqrt(__t);
- if (__z.real() < _Tp())
- __t = -__t;
-
- return std::log(__t + __z);
+ // Kahan's formula.
+ return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0)))
+ + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0))));
}
#if _GLIBCXX_USE_C99_COMPLEX_TR1