public inbox for cygwin-cvs@sourceware.org help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org> To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: take hypotl function from Mingw-w64 Date: Mon, 19 Apr 2021 10:47:20 +0000 (GMT) [thread overview] Message-ID: <20210419104720.E90623953C14@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=183e5f0a15f44f9a1d5d69ef0ffcfcce1ce1e680 commit 183e5f0a15f44f9a1d5d69ef0ffcfcce1ce1e680 Author: Corinna Vinschen <corinna@vinschen.de> Date: Mon Apr 19 12:37:44 2021 +0200 Cygwin: take hypotl function from Mingw-w64 The simple newlib hypotl for real long double architectures is too simple at this point. It's implemented as a real call to sqrtl(x^2+y^2). This has a fatal tendency to overflow for big input numbers. Hypotl isn't supposed to do that if the result would still be valid in range of long double. Given the complexity of implementing hypotl for various architectures, we just take the hypotl function from Mingw-w64, which is in the public domain. Even though this hypotl is an architecture-independent implementation, we can't use it for newlib yet, unfortunately, because it requires logbl under the hood. Logbl is yet another function missing in newlib for real long double architectures. Signed-off-by: Corinna Vinschen <corinna@vinschen.de> Diff: --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/math/hypotl.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 73d9b37fd..a5a1e3f16 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -212,6 +212,7 @@ MATH_OFILES:= \ fminl.o \ fmodl.o \ frexpl.o \ + hypotl.o \ ilogbl.o \ internal_logl.o \ isinf.o \ diff --git a/winsup/cygwin/math/hypotl.c b/winsup/cygwin/math/hypotl.c new file mode 100644 index 000000000..563aeb498 --- /dev/null +++ b/winsup/cygwin/math/hypotl.c @@ -0,0 +1,82 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include <math.h> +#include <float.h> +#include <errno.h> + +/* +This implementation is based largely on Cephes library +function cabsl (cmplxl.c), which bears the following notice: + +Cephes Math Library Release 2.1: January, 1989 +Copyright 1984, 1987, 1989 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + +/* + Modified for use in libmingwex.a + 02 Sept 2002 Danny Smith <dannysmith@users.sourceforege.net> + Calls to ldexpl replaced by logbl and calls to frexpl replaced + by scalbnl to avoid duplicated range checks. +*/ + +#define PRECL 32 + +long double +hypotl (long double x, long double y) +{ + int exx; + int eyy; + int scale; + long double xx =fabsl(x); + long double yy =fabsl(y); + if (!isfinite(xx) || !isfinite(yy)) + { + /* Annex F.9.4.3, hypot returns +infinity if + either component is an infinity, even when the + other component is NaN. */ + return (isinf(xx) || isinf(yy)) ? INFINITY : NAN; + } + + if (xx == 0.0L) + return yy; + if (yy == 0.0L) + return xx; + + /* Get exponents */ + exx = logbl (xx); + eyy = logbl (yy); + + /* Check if large differences in scale */ + scale = exx - eyy; + if ( scale > PRECL) + return xx; + if ( scale < -PRECL) + return yy; + + /* Exponent of approximate geometric mean (x 2) */ + scale = (exx + eyy) >> 1; + + /* Rescale: Geometric mean is now about 2 */ + x = scalbnl(xx, -scale); + y = scalbnl(yy, -scale); + + xx = sqrtl(x * x + y * y); + + /* Check for overflow and underflow */ + exx = logbl(xx); + exx += scale; + if (exx > LDBL_MAX_EXP) + { + errno = ERANGE; + return INFINITY; + } + if (exx < LDBL_MIN_EXP) + return 0.0L; + + /* Undo scaling */ + return (scalbnl (xx, scale)); +}
reply other threads:[~2021-04-19 10:47 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210419104720.E90623953C14@sourceware.org \ --to=corinna@sourceware.org \ --cc=cygwin-cvs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).