Message ID | 20240911140646.2143-3-fabian.schriever@gtd-gmbh.de |
---|---|
State | New |
Headers |
Return-Path: <newlib-bounces~patchwork=sourceware.org@sourceware.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2BD6B385EC20 for <patchwork@sourceware.org>; Wed, 11 Sep 2024 14:12:31 +0000 (GMT) X-Original-To: newlib@sourceware.org Delivered-To: newlib@sourceware.org Received: from gtd-gmbh.de (mail.gtd.eu [46.24.46.35]) by sourceware.org (Postfix) with ESMTPS id 721DA3858C98 for <newlib@sourceware.org>; Wed, 11 Sep 2024 14:11:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 721DA3858C98 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gtd-gmbh.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gtd-gmbh.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 721DA3858C98 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=46.24.46.35 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726063919; cv=none; b=r731r5ZiImpsQCSr5uo2DzRYCIa0BGaHziuQchUBlRxchIl8/FNsFSBm53fdCE3r/CwhUodAJEeQJA+8nAN/uOqjYnaplnc397FBB7NsWnY2ypuuZL4qoiJ5KAOz90wB99CisAfprnf3xS4OLGqPoBAAX16RP72lwCEfOL2SrIU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726063919; c=relaxed/simple; bh=QwTYBlmXSXgls6rORek9tK7hiW5bDhEL19LbCM8bflo=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=OzX4Htko7nNt87DZsPgFoZbNdN+Gzev+QP4qWbxjBxOu3XpOFA+t+V7SJXPTi+xvH1mPt7szm38hA3NgL2F/+O9zJVRNTsdgxW7ZxEudEI5Tr+CTY37uje4yj8eQthjWCAfCCRafN5mxtpMU6NTHURu5ZoJP6R+ZkR8rugdFm38= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=simple; d=gtd-gmbh.de; s=nk2048220908; t=1726063722; x=1726668522; i=fabian.schriever@gtd-gmbh.de; q=dns/txt; h=From:To:Cc:Subject: Date:Message-Id:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=QwTYBlmXSXgls6rORek9tK7hiW5bDhEL19 LbCM8bflo=; b=LwDY7MsRcl3irOCoUVBFgG8IJodrO4EmYj14Gr29E+aYy9xZ0r NtJ9+zwll6ZwyGsOdRFfB7FlqEzudWFKCzKGicuQ3+hVHxOz/DuBnHRrfxqOfnU8 DmVXYo6+2OSfYmX2i4r9fJ/8dx7LPfw+ytTUR2RJRHnTLUBNSRJNL3RsQ2kLXLzi eTNb8iWsgYybn3c2y0y5NGdntjeywA4nr68rjK5MZjwd5DySax5aiOEymhr/tGPd LHrvH2rXWsmXPsmb2N9GF76jaM0B5wSkwb5j/EfL95bXqEntAMzFZnjOD6VmV3yD LDilZz3Tx+k+z8acnWfH1bfHo3Wia0S+06OQ== X-MDAV-Result: clean X-MDAV-Processed: gtd-gmbh.de, Wed, 11 Sep 2024 16:08:42 +0200 Received: from localhost.localdomain [(95.223.184.231)] by gtd-gmbh.de (MDaemon PRO v24.0.1) with ESMTPSA id md5001020706855.msg; Wed, 11 Sep 2024 16:08:40 +0200 X-Spam-Processed: gtd-gmbh.de, Wed, 11 Sep 2024 16:08:40 +0200 (not processed: message from trusted or authenticated source) X-MDRemoteIP: 95.223.184.231 X-MDHelo: localhost.localdomain X-MDArrival-Date: Wed, 11 Sep 2024 16:08:40 +0200 X-Authenticated-Sender: fabian.schriever@gtd-gmbh.de X-Return-Path: prvs=19845911f7=fabian.schriever@gtd-gmbh.de X-Envelope-From: fabian.schriever@gtd-gmbh.de X-MDaemon-Deliver-To: newlib@sourceware.org From: Fabian Schriever <fabian.schriever@gtd-gmbh.de> To: newlib@sourceware.org Cc: Paul.Zimmermann@inria.fr, Fabian Schriever <fabian.schriever@gtd-gmbh.de> Subject: [PATCH 2/3] powf: Fixed 2 bugs in the computation /* t_h=ax+bp[k] High */. (FreeBSD) Date: Wed, 11 Sep 2024 16:06:45 +0200 Message-Id: <20240911140646.2143-3-fabian.schriever@gtd-gmbh.de> X-Mailer: git-send-email 2.33.0.windows.1 In-Reply-To: <20240911140646.2143-1-fabian.schriever@gtd-gmbh.de> References: <20240911140646.2143-1-fabian.schriever@gtd-gmbh.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-MDCFSigsAdded: gtd-gmbh.de X-Spam-Status: No, score=-9.8 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: newlib@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Newlib mailing list <newlib.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/newlib>, <mailto:newlib-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/newlib/> List-Post: <mailto:newlib@sourceware.org> List-Help: <mailto:newlib-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/newlib>, <mailto:newlib-request@sourceware.org?subject=subscribe> Errors-To: newlib-bounces~patchwork=sourceware.org@sourceware.org |
Series |
Fix powf inaccuracies up to ~169 ULP reported by Paul Zimmermann
|
|
Commit Message
Fabian Schriever
Sept. 11, 2024, 2:06 p.m. UTC
(1) The bit for the 1.0 part of bp[k] was right shifted by 4. This seems to have been caused by a typo in converting e_pow.c to e_powf.c. (2) The lower 12 bits of ax+bp[k] were not discarded, so t_h was actually plain ax+bp[k]. This seems to have been caused by a logic error in the conversion. These bugs gave wrong results like: powf(-1.1, 101.0) = -15158.703 (should be -15158.707) hex values: BF8CCCCD 42CA0000 C66CDAD0 C66CDAD4 Fixing (1) gives a result wrong in the opposite direction (hex C66CDAD8), and fixing (2) gives the correct result. ucbtest has been reporting this particular wrong result on i386 systems with unpatched libraries for 9 years. I finally figured out the extent of the bugs. On i386's they are normally hidden by extra precision. We use the trick of representing floats as a sum of 2 floats (one much smaller) to get extra precision in intermediate calculations without explicitly using more than float precision. This trick is just a pessimization when extra precision is available naturally (as it always is when dealing with IEEE single precision, so the float precision part of the library is mostly misimplemented). (1) and (2) break the trick in different ways, except on i386's it turns out that the intermediate calculations are done in enough precision to mask both the bugs and the limited precision of the float variables (as far as ucbtest can check). ucbtest detects the bugs because it forces float precision, but this is not a normal mode of operation so the bug normally has little effect on i386's. On systems that do float arithmetic in float precision, e.g., amd64's, there is no accidental extra precision and the bugs just give wrong results. Reference: https://github.com/freebsd/freebsd-src/commit/12be4e0d5a54a6750913aee2564d164baa71f0dc Original Author: Bruce Evans --- newlib/libm/math/ef_pow.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Comments
On 2024-09-11 16:06, Fabian Schriever wrote: > (1) The bit for the 1.0 part of bp[k] was right shifted by 4. This > seems to have been caused by a typo in converting e_pow.c to > e_powf.c. > (2) The lower 12 bits of ax+bp[k] were not discarded, so t_h was > actually plain ax+bp[k]. This seems to have been caused by a logic > error in the conversion. > > These bugs gave wrong results like: > > powf(-1.1, 101.0) = -15158.703 (should be -15158.707) > hex values: BF8CCCCD 42CA0000 C66CDAD0 C66CDAD4 > > Fixing (1) gives a result wrong in the opposite direction > (hex C66CDAD8), and fixing (2) gives the correct result. > > ucbtest has been reporting this particular wrong result on i386 systems > with unpatched libraries for 9 years. I finally figured out the extent > of the bugs. On i386's they are normally hidden by extra precision. > We use the trick of representing floats as a sum of 2 floats (one much > smaller) to get extra precision in intermediate calculations without > explicitly using more than float precision. This trick is just a > pessimization when extra precision is available naturally (as it always > is when dealing with IEEE single precision, so the float precision part > of the library is mostly misimplemented). (1) and (2) break the trick > in different ways, except on i386's it turns out that the intermediate > calculations are done in enough precision to mask both the bugs and > the limited precision of the float variables (as far as ucbtest can > check). > > ucbtest detects the bugs because it forces float precision, but this > is not a normal mode of operation so the bug normally has little effect > on i386's. > > On systems that do float arithmetic in float precision, e.g., amd64's, > there is no accidental extra precision and the bugs just give wrong > results. > > Reference: https://github.com/freebsd/freebsd-src/commit/12be4e0d5a54a6750913aee2564d164baa71f0dc > Original Author: Bruce Evans > --- > newlib/libm/math/ef_pow.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/newlib/libm/math/ef_pow.c b/newlib/libm/math/ef_pow.c > index 4ceba3d24..c7b1975c3 100644 > --- a/newlib/libm/math/ef_pow.c > +++ b/newlib/libm/math/ef_pow.c > @@ -173,7 +173,8 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ > GET_FLOAT_WORD(is,s_h); > SET_FLOAT_WORD(s_h,is&0xfffff000); > /* t_h=ax+bp[k] High */ > - SET_FLOAT_WORD(t_h,((ix>>1)|0x20000000)+0x0040000+(k<<21)); > + is = ((ix >> 1) & 0xfffff000U) | 0x20000000; > + SET_FLOAT_WORD(t_h, is + 0x00400000 + (k << 21)); The indentation of the above 2 added lines appears to be incorrect. Kind regards, Torbjörn > t_l = ax - (t_h-bp[k]); > s_l = v*((u-s_h*t_h)-s_h*t_l); > /* compute log(ax) */
diff --git a/newlib/libm/math/ef_pow.c b/newlib/libm/math/ef_pow.c index 4ceba3d24..c7b1975c3 100644 --- a/newlib/libm/math/ef_pow.c +++ b/newlib/libm/math/ef_pow.c @@ -173,7 +173,8 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ GET_FLOAT_WORD(is,s_h); SET_FLOAT_WORD(s_h,is&0xfffff000); /* t_h=ax+bp[k] High */ - SET_FLOAT_WORD(t_h,((ix>>1)|0x20000000)+0x0040000+(k<<21)); + is = ((ix >> 1) & 0xfffff000U) | 0x20000000; + SET_FLOAT_WORD(t_h, is + 0x00400000 + (k << 21)); t_l = ax - (t_h-bp[k]); s_l = v*((u-s_h*t_h)-s_h*t_l); /* compute log(ax) */