------- 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

Reply via email to