Bug 160759
Summary: | tanh(X) gives wrong results with complex X | ||
---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | Dmitri A. Sergatskov <dasergatskov> |
Component: | glibc | Assignee: | Jakub Jelinek <jakub> |
Status: | CLOSED RAWHIDE | QA Contact: | |
Severity: | high | Docs Contact: | |
Priority: | medium | ||
Version: | 4 | CC: | drepper |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | i386 | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | 2.3.90-2 | Doc Type: | Bug Fix |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2005-07-10 20:25:00 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Dmitri A. Sergatskov
2005-06-17 05:28:52 UTC
It's the underlying ctanh implementation: #include <complex.h> #include <math.h> #include <stdio.h> int main (void) { _Complex double c, d; __real__ c = 0; __imag__ c = 3.1415926535/2.0; printf ("x %g + %gi\n", __real__ c, __imag__ c); d = csinh (c); printf ("sinh %g + %gi\n", __real__ d, __imag__ d); d = ccosh (c); printf ("cosh %g + %gi\n", __real__ d, __imag__ d); d = csinh (c) / ccosh (c); printf ("sinh/cosh %g + %gi\n", __real__ d, __imag__ d); d = ctanh (c); printf ("tanh %g + %gi\n", __real__ d, __imag__ d); d = ccosh (c) / csinh (c); printf ("cosh/sinh %g + %gi\n", __real__ d, __imag__ d); d = 1.0/ctanh (c); printf ("1/tanh %g + %gi\n", __real__ d, __imag__ d); return 0; } x 0 + 1.5708i sinh 0 + 1i cosh 4.48966e-11 + 0i sinh/cosh 0 + 2.22734e+10i tanh nan + infi cosh/sinh 0 + -4.48966e-11i 1/tanh nan + nani tanh(z) is (e^z-e^-z)/(e^z+e^-z) and e^(i*pi/2) is i, e^(-i*pi/2) is -i, so 2i/0. 2i/0 is nan + nani I think, though am not 100% sure about that. The fact that sinh/cosh gives different number is just a matter of imprecise calculations. 2*i/0 is Inf (or i*Inf, if it matters) (0/2i is obviously 0). (One way of thinking about these is to write z = r*exp(i*w), where r is real amplitude and w is real phase. This way say lim(x/y) == lim((r_x)/(r_y)).) I noticed the bug while calculatin coth(i*x) as 1/tanh(i*x). coth(i*pi/2) must be zero. Also the difference between (0 + -4.48966e-11i) and (nan + nani) is more than machine precision. The bottom line is: glibc in FC3 got it right and in FC4 does not. "glibc in FC3 got it right and in FC4 does not" This is not true, FC4, FC3, RHEL4 and RHEL3 glibc's behave all the same. Only GCC 3.4.x and earlier did not use c{sin,cos,tan}h in <complex>. Fair enough. The correct(ed) statement is that the test program gives right answers in FC3 and wrong answers in FC4 and that needs fixing. Also, this is might be somewhat off-topic, but there is a FDLIBM math library on netlib which as far as I can tell has GNU-compatible license (it is developed at Sun). This library often used as a reference library for math functions. Any reason GNU libm cannot use it? Sincerely, Dmitri. GNU libm is heavily based on fdlibm. fdlibm does not have complex math stuff in it though. I've added some code upstream which reduces the error. Changes are in glibc-2.3.90-2. |