From 153108f96fad542bf772b02abb95c748743b27da Mon Sep 17 00:00:00 2001 From: Andreas Enge Date: Wed, 30 Nov 2022 18:01:50 +0100 Subject: [PATCH] Correct signs of 0 parts in exact Karatsuba multiplication. * src/mul.c (mpc_mul_karatsuba): Clear sign if a part of a result is an exact 0. * tests/mul.dat: Add test. --- src/mul.c | 15 ++++++++++++++- tests/mul.dat | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mul.c b/src/mul.c index 9ca95e1..e1574a1 100644 --- a/src/mul.c +++ b/src/mul.c @@ -1,6 +1,6 @@ /* mpc_mul -- Multiply two complex numbers -Copyright (C) 2002, 2004, 2005, 2008, 2009, 2010, 2011, 2012, 2016, 2020 INRIA +Copyright (C) 2002, 2004, 2005, 2008, 2009, 2010, 2011, 2012, 2016, 2020, 2022 INRIA This file is part of GNU MPC. @@ -219,6 +219,7 @@ mpc_mul_karatsuba (mpc_ptr rop, mpc_srcptr op1, mpc_srcptr op2, mpc_rnd_t rnd) imaginary part is used). If this fails, we have to start again and need the correct values of op1 and op2. So we just create a new variable for the result in this case. */ + mpfr_ptr ref; int loop; const int MAX_MUL_LOOP = 1; @@ -424,6 +425,18 @@ mpc_mul_karatsuba (mpc_ptr rop, mpc_srcptr op1, mpc_srcptr op2, mpc_rnd_t rnd) } } + /* Clear potential signs of 0. */ + if (!inex_re) { + ref = mpc_realref (result); + if (mpfr_zero_p (ref) && mpfr_signbit (ref)) + MPFR_CHANGE_SIGN (ref); + } + if (!inex_im) { + ref = mpc_imagref (result); + if (mpfr_zero_p (ref) && mpfr_signbit (ref)) + MPFR_CHANGE_SIGN (ref); + } + mpc_set (rop, result, MPC_RNDNN); } diff --git a/tests/mul.dat b/tests/mul.dat index ad2515a..b560098 100644 --- a/tests/mul.dat +++ b/tests/mul.dat @@ -184,3 +184,6 @@ + 0 2 1 2 0x2p-536870913 2 1 2 0x1p-536870913 2 1 2 0x1p-536870913 N N 0 - 2 0 2 1 2 0x1p-536870913 2 1 2 1 2 0x1p-536870913 N N + +# error in sign of 0 with exact Karatsuba found on 2022-11-30 +0 0 1473 -50 1473 +0 20 1 20 2 20 -10 20 20 N N -- 2.33.0