aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/libm-ieee754
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/libm-ieee754')
-rw-r--r--sysdeps/libm-ieee754/s_csqrt.c31
-rw-r--r--sysdeps/libm-ieee754/s_csqrtf.c31
-rw-r--r--sysdeps/libm-ieee754/s_csqrtl.c31
3 files changed, 51 insertions, 42 deletions
diff --git a/sysdeps/libm-ieee754/s_csqrt.c b/sysdeps/libm-ieee754/s_csqrt.c
index cda23c702d..ae106bdad8 100644
--- a/sysdeps/libm-ieee754/s_csqrt.c
+++ b/sysdeps/libm-ieee754/s_csqrt.c
@@ -1,5 +1,5 @@
/* Complex square root of double value.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Based on an algorithm by Stephen L. Moshier <moshier@world.std.com>.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -84,22 +84,25 @@ __csqrt (__complex__ double x)
}
else
{
-#if 0 /* FIXME: this is broken. */
- __complex__ double q;
- double t, r;
+#if 0
+ double d, r, s;
- if (fabs (__imag__ x) < 2.0e-4 * fabs (__real__ x))
- t = 0.25 * __imag__ x * (__imag__ x / __real__ x);
+ d = __ieee754_hypot (__real__ x, __imag__ x);
+ /* Use the identity 2 Re res Im res = Im x
+ to avoid cancellation error in d +/- Re x. */
+ if (__real__ x > 0)
+ {
+ r = __ieee754_sqrt (0.5 * d + 0.5 * __real__ x);
+ s = (0.5 * __imag__ x) / r;
+ }
else
- t = 0.5 * (__ieee754_hypot (__real__ x, __imag__ x) - __real__ x);
-
- r = __ieee754_sqrt (t);
-
- __real__ q = __imag__ x / (2.0 * r);
- __imag__ q = r;
+ {
+ s = __ieee754_sqrt (0.5 * d - 0.5 * __real__ x);
+ r = (0.5 * __imag__ x) / s;
+ }
- /* Heron iteration in complex arithmetic. */
- res = 0.5 * (q + q / x);
+ __real__ res = r;
+ __imag__ res = __copysign (s, __imag__ x);
#else
double d, imag;
diff --git a/sysdeps/libm-ieee754/s_csqrtf.c b/sysdeps/libm-ieee754/s_csqrtf.c
index 5fdf2c1d66..015b0cd57f 100644
--- a/sysdeps/libm-ieee754/s_csqrtf.c
+++ b/sysdeps/libm-ieee754/s_csqrtf.c
@@ -1,5 +1,5 @@
/* Complex square root of float value.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Based on an algorithm by Stephen L. Moshier <moshier@world.std.com>.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -84,22 +84,25 @@ __csqrtf (__complex__ float x)
}
else
{
-#if 0 /* FIXME: this is broken. */
- __complex__ float q;
- float t, r;
+#if 0
+ float d, r, s;
- if (fabsf (__imag__ x) < 2.0e-4 * fabsf (__real__ x))
- t = 0.25 * __imag__ x * (__imag__ x / __real__ x);
+ d = __ieee754_hypotf (__real__ x, __imag__ x);
+ /* Use the identity 2 Re res Im res = Im x
+ to avoid cancellation error in d +/- Re x. */
+ if (__real__ x > 0)
+ {
+ r = __ieee754_sqrtf (0.5f * d + 0.5f * __real__ x);
+ s = (0.5f * __imag__ x) / r;
+ }
else
- t = 0.5 * (__ieee754_hypotf (__real__ x, __imag__ x) - __real__ x);
-
- r = __ieee754_sqrtf (t);
-
- __real__ q = __imag__ x / (2.0 * r);
- __imag__ q = r;
+ {
+ s = __ieee754_sqrtf (0.5f * d - 0.5f * __real__ x);
+ r = (0.5f * __imag__ x) / s;
+ }
- /* Heron iteration in complex arithmetic. */
- res = 0.5 * (q + q / x);
+ __real__ res = r;
+ __imag__ res = __copysignf (s, __imag__ x);
#else
float d, imag;
diff --git a/sysdeps/libm-ieee754/s_csqrtl.c b/sysdeps/libm-ieee754/s_csqrtl.c
index b772709947..4b7ed983d8 100644
--- a/sysdeps/libm-ieee754/s_csqrtl.c
+++ b/sysdeps/libm-ieee754/s_csqrtl.c
@@ -1,5 +1,5 @@
/* Complex square root of long double value.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Based on an algorithm by Stephen L. Moshier <moshier@world.std.com>.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -84,22 +84,25 @@ __csqrtl (__complex__ long double x)
}
else
{
-#if 0 /* FIXME: this is broken. */
- __complex__ long double q;
- long double t, r;
+#if 0
+ long double d, r, s;
- if (fabsl (__imag__ x) < 2.0e-4 * fabsl (__real__ x))
- t = 0.25 * __imag__ x * (__imag__ x / __real__ x);
+ d = __ieee754_hypotl (__real__ x, __imag__ x);
+ /* Use the identity 2 Re res Im res = Im x
+ to avoid cancellation error in d +/- Re x. */
+ if (__real__ x > 0)
+ {
+ r = __ieee754_sqrtl (0.5L * d + 0.5L * __real__ x);
+ s = (0.5L * __imag__ x) / r;
+ }
else
- t = 0.5 * (__ieee754_hypotl (__real__ x, __imag__ x) - __real__ x);
-
- r = __ieee754_sqrtl (t);
-
- __real__ q = __imag__ x / (2.0 * r);
- __imag__ q = r;
+ {
+ s = __ieee754_sqrtl (0.5L * d - 0.5L * __real__ x);
+ r = (0.5L * __imag__ x) / s;
+ }
- /* Heron iteration in complex arithmetic. */
- res = 0.5 * (q + q / x);
+ __real__ res = r;
+ __imag__ res = __copysignl (s, __imag__ x);
#else
long double d, imag;