From patchwork Wed Apr 2 14:26:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 388 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx22.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 299A73600C2 for ; Wed, 2 Apr 2014 07:26:59 -0700 (PDT) Received: by homiemail-mx22.g.dreamhost.com (Postfix, from userid 14307373) id CCA3D45171A8; Wed, 2 Apr 2014 07:26:58 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx22.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx22.g.dreamhost.com (Postfix) with ESMTPS id A44C6452A601 for ; Wed, 2 Apr 2014 07:26:58 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; q=dns; s=default; b=HQcPRFphb6XeyG4i35/T/YWFXJ/hW rTuO20Awwg5blKHm/99VJ7O5/gOB7xrSxppPEm95dNNRReKDgDtFWyjlaVTn10EW x/C8d07FUYMyJcxMckcy097vIzhiNJVWQRQvRWZB9UMqsa52yQ214sDRxOcg95AA eZ79BLkJzuIEKg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; s=default; bh=9Oe9opzkRphG0N1cx8L7tw+gXOY=; b=lGS Uy6CBTKLLF/3OnRBZgf1tHBBYN/5MxGCQb5MBR+rGn/RL23pLWZwTPxEudw8SYsB h5TCSBLBXAfikryaCqqDiRwVk7xSQ8T1aRDPifKKQaoZACb4CWFYQ0puhVtD0kVl 10P4kQ87Hos1D5zKFpU4DUlOIxWv9SbsGehO5qqE= Received: (qmail 26699 invoked by alias); 2 Apr 2014 14:26:55 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 26684 invoked by uid 89); 2 Apr 2014 14:26:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.6 required=5.0 tests=AWL, BAYES_00, KAM_STOCKTIP autolearn=no version=3.3.2 X-HELO: relay1.mentorg.com Date: Wed, 2 Apr 2014 14:26:44 +0000 From: "Joseph S. Myers" To: Subject: Fix catan, catanh, __ieee754_logf in round-downward mode (bug 16799, bug 16800) Message-ID: MIME-Version: 1.0 X-DH-Original-To: glibc@patchwork.siddhesh.in This patch fixes incorrect results from catan and catanh of certain special inputs in round-downward mode (bug 16799), and incorrect results of __ieee754_logf (+/-0) in round-downward mode (bug 16800) that show up through catan/catanh when tested in all rounding modes, but not directly in the testing for logf because the bug gets hidden by the wrappers. Both bugs involve a zero that should be +0 being -0 instead: one computed as (1-x)*(1+x) in the catan/catanh case, and one as (x-x) in the logf case. The fixes ensure positive zero is used. Testing of catan and catanh in all rounding modes is duly enabled. I expect there are various other bugs in special cases in __ieee754_* functions that are normally hidden by the wrappers but would show up for testing with -lieee (or in future with -fno-math-errno if we replace -lieee and _LIB_VERSION with compile-time redirection to new *_noerrno symbol names). Tested x86_64 and x86 and ulps updated accordingly. 2014-04-02 Joseph Myers [BZ #16799] [BZ #16800] * math/s_catan.c (__catan): Avoid passing -0 denominator to atan2 with 0 numerator. * math/s_catanf.c (__catanf): Likewise. * math/s_catanh.c (__catanh): Likewise. * math/s_catanhf.c (__catanhf): Likewise. * math/s_catanhl.c (__catanhl): Likewise. * math/s_catanl.c (__catanl): Likewise. * sysdeps/ieee754/flt-32/e_logf.c (__ieee754_logf): Always divide by positive zero when computing -Inf result. * math/libm-test.inc (catan_test): Use ALL_RM_TEST. (catanh_test): Likewise. * sysdeps/i386/fpu/libm-test-ulps: Update. * sysdeps/x86_64/fpu/libm-test-ulps: Likewise. diff --git a/math/libm-test.inc b/math/libm-test.inc index c6279e7..5e6789f 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -5239,9 +5239,7 @@ static const struct test_c_c_data catan_test_data[] = static void catan_test (void) { - START (catan, 0); - RUN_TEST_LOOP_c_c (catan, catan_test_data, ); - END_COMPLEX; + ALL_RM_TEST (catan, 0, catan_test_data, RUN_TEST_LOOP_c_c, END_COMPLEX); } static const struct test_c_c_data catanh_test_data[] = @@ -5746,9 +5744,7 @@ static const struct test_c_c_data catanh_test_data[] = static void catanh_test (void) { - START (catanh, 0); - RUN_TEST_LOOP_c_c (catanh, catanh_test_data, ); - END_COMPLEX; + ALL_RM_TEST (catanh, 0, catanh_test_data, RUN_TEST_LOOP_c_c, END_COMPLEX); } static const struct test_f_f_data cbrt_test_data[] = diff --git a/math/s_catan.c b/math/s_catan.c index d6552d8..0cfa924 100644 --- a/math/s_catan.c +++ b/math/s_catan.c @@ -89,7 +89,11 @@ __catan (__complex__ double x) } if (absy < DBL_EPSILON / 2.0) - den = (1.0 - absx) * (1.0 + absx); + { + den = (1.0 - absx) * (1.0 + absx); + if (den == -0.0) + den = 0.0; + } else if (absx >= 1.0) den = (1.0 - absx) * (1.0 + absx) - absy * absy; else if (absx >= 0.75 || absy >= 0.5) diff --git a/math/s_catanf.c b/math/s_catanf.c index 41e419d..b478684 100644 --- a/math/s_catanf.c +++ b/math/s_catanf.c @@ -90,7 +90,11 @@ __catanf (__complex__ float x) } if (absy < FLT_EPSILON / 2.0f) - den = (1.0f - absx) * (1.0f + absx); + { + den = (1.0f - absx) * (1.0f + absx); + if (den == -0.0f) + den = 0.0f; + } else if (absx >= 1.0f) den = (1.0f - absx) * (1.0f + absx) - absy * absy; else if (absx >= 0.75f || absy >= 0.5f) diff --git a/math/s_catanh.c b/math/s_catanh.c index 2ba1298..7ef9142 100644 --- a/math/s_catanh.c +++ b/math/s_catanh.c @@ -110,7 +110,11 @@ __catanh (__complex__ double x) } if (absy < DBL_EPSILON / 2.0) - den = (1.0 - absx) * (1.0 + absx); + { + den = (1.0 - absx) * (1.0 + absx); + if (den == -0.0) + den = 0.0; + } else if (absx >= 1.0) den = (1.0 - absx) * (1.0 + absx) - absy * absy; else if (absx >= 0.75 || absy >= 0.5) diff --git a/math/s_catanhf.c b/math/s_catanhf.c index 0ee69a5..0e55aff 100644 --- a/math/s_catanhf.c +++ b/math/s_catanhf.c @@ -112,7 +112,11 @@ __catanhf (__complex__ float x) } if (absy < FLT_EPSILON / 2.0f) - den = (1.0f - absx) * (1.0f + absx); + { + den = (1.0f - absx) * (1.0f + absx); + if (den == -0.0f) + den = 0.0f; + } else if (absx >= 1.0f) den = (1.0f - absx) * (1.0f + absx) - absy * absy; else if (absx >= 0.75f || absy >= 0.5f) diff --git a/math/s_catanhl.c b/math/s_catanhl.c index 537bb3e..6410afe 100644 --- a/math/s_catanhl.c +++ b/math/s_catanhl.c @@ -118,7 +118,11 @@ __catanhl (__complex__ long double x) } if (absy < LDBL_EPSILON / 2.0L) - den = (1.0L - absx) * (1.0L + absx); + { + den = (1.0L - absx) * (1.0L + absx); + if (den == -0.0L) + den = 0.0L; + } else if (absx >= 1.0L) den = (1.0L - absx) * (1.0L + absx) - absy * absy; else if (absx >= 0.75L || absy >= 0.5L) diff --git a/math/s_catanl.c b/math/s_catanl.c index cea9282..dd01d16 100644 --- a/math/s_catanl.c +++ b/math/s_catanl.c @@ -97,7 +97,11 @@ __catanl (__complex__ long double x) } if (absy < LDBL_EPSILON / 2.0L) - den = (1.0L - absx) * (1.0L + absx); + { + den = (1.0L - absx) * (1.0L + absx); + if (den == -0.0L) + den = 0.0L; + } else if (absx >= 1.0L) den = (1.0L - absx) * (1.0L + absx) - absy * absy; else if (absx >= 0.75L || absy >= 0.5L) diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps index 0252d5b..aea6c51 100644 --- a/sysdeps/i386/fpu/libm-test-ulps +++ b/sysdeps/i386/fpu/libm-test-ulps @@ -383,6 +383,54 @@ ifloat: 1 ildouble: 1 ldouble: 1 +Function: Real part of "catan_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: Real part of "catan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: Real part of "catan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + Function: Real part of "catanh": double: 1 float: 1 @@ -391,6 +439,54 @@ ifloat: 1 ildouble: 1 ldouble: 1 +Function: Real part of "catanh_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "catanh_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "catanh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + Function: "cbrt": double: 1 idouble: 1 diff --git a/sysdeps/ieee754/flt-32/e_logf.c b/sysdeps/ieee754/flt-32/e_logf.c index 7da6489..cf75e11 100644 --- a/sysdeps/ieee754/flt-32/e_logf.c +++ b/sysdeps/ieee754/flt-32/e_logf.c @@ -41,7 +41,7 @@ __ieee754_logf(float x) k=0; if (ix < 0x00800000) { /* x < 2**-126 */ if (__builtin_expect((ix&0x7fffffff)==0, 0)) - return -two25/(x-x); /* log(+-0)=-inf */ + return -two25/zero; /* log(+-0)=-inf */ if (__builtin_expect(ix<0, 0)) return (x-x)/(x-x); /* log(-#) = NaN */ k -= 25; x *= two25; /* subnormal number, scale up x */ diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index 1b6ebe2..4ba83a4 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -410,6 +410,54 @@ ifloat: 1 ildouble: 1 ldouble: 1 +Function: Real part of "catan_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Real part of "catan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: Real part of "catan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + Function: Real part of "catanh": double: 1 float: 1 @@ -422,6 +470,54 @@ Function: Imaginary part of "catanh": float: 1 ifloat: 1 +Function: Real part of "catanh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Real part of "catanh_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Real part of "catanh_upward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + Function: "cbrt": double: 1 float: 1