------- Comment #3 from tomdean at speakeasy dot org 2010-04-19 23:33 ------- Subject: Re: Tanh Returns Incorrect Value
On Mon, 2010-04-19 at 22:56 +0000, pinskia at gcc dot gnu dot org wrote: > > ------- Comment #1 from pinskia at gcc dot gnu dot org 2010-04-19 22:56 > ------- > That is because you are using the double version of ctanh rather than the long > double version for the C case. > > Changing the C testcase to use ctanhl and you get the same value for the C/C++ > cases. > > The problem remains. I used a long double to try to demonstrate overflow. Changing all the code to use ctanhl, csinhl, ccoshl, only changed the point at wiich overflow occurs and ctanhl() returns an incorrect value. Note: limit(tanh(n*(1+I)),n=infinity) == 1 Therefore, if the argument to ctanh is not nan or inf, ctanh should return 1 at and above overflow for the type. I only calculated s/c, demonstrating the overflow to another group, octave. Sorry for sending the wrong code, which distracted from the problem. Here is the code I use for the test. As mult increases, you can see the overflow happening. >./test-tanh-c 5678 libc version 2.10.1 libc release stable arg = 5678.000000 + 5678.000000 * i sinh (arg) = -1.745126e+2465 + -3.818036e+2465 * i cosh (arg) = -1.745126e+2465 + -3.818036e+2465 * i s/c = 1.000000 + -0.000000 * i tanh (arg) = 1.000000 + 0.000000 * i >./teat-tanh-c 5679 libc version 2.10.1 libc release stable arg = 5679.000000 + 5679.000000 * i sinh (arg) = 6.170148e+2465 + -9.599250e+2465 * i cosh (arg) = 6.170148e+2465 + -9.599250e+2465 * i s/c = 1.000000 + -0.000000 * i tanh (arg) = nan + -0.000000 * i <==== OVERFLOW??? #include <math.h> #include <complex.h> #include <stdio.h> #define _GNU_SOURCE #include <gnu/libc-version.h> int main (int argc, char **argv) { long double complex arg = 1 + _Complex_I; long double complex s, c, r, t; long mult; if (argc == 2) { mult = atol(argv[1]); } else { mult = 50000L; } arg *= (long double)mult; s = csinhl (arg); c = ccoshl (arg); r = s / c; t = ctanhl (arg); printf ("libc version %s\n", gnu_get_libc_version ()); printf ("libc release %s\n", gnu_get_libc_release ()); printf ("arg = %Lf + %Lf * i\n", creall (arg), cimagl (arg)); printf ("sinh (arg) = %Le + %Le * i\n", creall (s), cimagl (s)); printf ("cosh (arg) = %Le + %Le * i\n", creall (c), cimagl (c)); printf("s/c = %Lf + %Lf * i\n", creall (r), cimagl (r)); printf ("tanh (arg) = %Lf + %Lf * i\n", creall (t), cimagl (t)); return 0; } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43802