Bug in gmp/mpfr/mpc, never ending ctan computation
Richard Biener
rguenther at suse.de
Mon Nov 19 10:14:49 UTC 2018
On Mon, 19 Nov 2018, Torbjörn Granlund wrote:
> [moved from gmp-devel]
>
>
> Richard Biener <rguenther at 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 <rguenther at suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
More information about the gmp-bugs
mailing list