On Mon, 19 Nov 2018, Torbjörn Granlund wrote:

> [moved from gmp-devel]
> 
> 
> Richard Biener <rguent...@suse.de> writes:
> 
>   For
> >
>   #include <complex.h>
> >
>   int main()
>   {
>     _Complex double x;
>     __real x = 3.09126495087690770626068115234375e+8;
>     __imag x = -4.045689747817175388336181640625e+8;
>     volatile _Complex double y = ctan (x);
>     return 0;
>   }
> 
> If we get a test case somewhat closer to GMP, then it is likely
> somebody will look at it.
> 
> I expect the maintainers of library called by gcc (mpc?) would be helped
> by seeing the actual call to their library.

OK, I can reproduce the issue with mpc 1.1.0, mpfr 3.1.4 and gmp 6.1.0
using

#include <mpc.h>
#include <mpfr.h>

int main()
{
  mpc_t m;
  mpc_init2 (m, 53);
  mpfr_set_str (mpc_realref (m), "3.09126495087690770626068115234375e+8", 
10, GMP_RNDN);
  mpfr_set_str (mpc_imagref (m), "-4.045689747817175388336181640625e+8", 
10, GMP_RNDN);
  mpfr_clear_flags ();
  mpc_tan (m, m, 0);
  return 0;
}

breaking at tan.c:189 and printing prec and then err I see

Breakpoint 1, mpc_tan (rop=0x7fffffffdd50, op=0x7fffffffdd50, rnd=0)
    at /space/rguenther/src/svn/trunk2/mpc/src/tan.c:189
189           prec += mpc_ceil_log2 (prec) + err;
$3 = 53
$4 = 7

Breakpoint 1, mpc_tan (rop=0x7fffffffdd50, op=0x7fffffffdd50, rnd=0)
    at /space/rguenther/src/svn/trunk2/mpc/src/tan.c:189
189           prec += mpc_ceil_log2 (prec) + err;
$5 = 66
$6 = 66

Breakpoint 1, mpc_tan (rop=0x7fffffffdd50, op=0x7fffffffdd50, rnd=0)
    at /space/rguenther/src/svn/trunk2/mpc/src/tan.c:189
189           prec += mpc_ceil_log2 (prec) + err;
$7 = 139
$8 = 139

...
Breakpoint 1, mpc_tan (rop=0x7fffffffdd50, op=0x7fffffffdd50, rnd=0)
    at /space/rguenther/src/svn/trunk2/mpc/src/tan.c:189
189           prec += mpc_ceil_log2 (prec) + err;
$29 = 303084
$30 = 303084
...

So somehow err ends up equal to prec and ever increasing?  Which means
we always end up in

      /* OP is no pure real nor pure imaginary, so in theory the real and
         imaginary parts of its tangent cannot be null. However due to
         rounding errors this might happen. Consider for example
         tan(1+14*I) = 1.26e-10 + 1.00*I. For small precision sin(op) and
         cos(op) differ only by a factor I, thus after mpc_div x = I and
         its real part is zero. */
      if (mpfr_zero_p (mpc_realref (x)) || mpfr_zero_p (mpc_imagref (x)))
        {
          err = prec; /* double precision */
          continue;
        }

As I questioned in the first followup I wonder if GCC can tell mpc
to not exceed 53bits of precision for the result?  Even with denormals
a precision of 303084 bits isn't possible?

Richard.

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)
_______________________________________________
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs

Reply via email to