From nobody Thu Aug 10 02:58:29 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4RLs7V0W8Gz4pvvc; Thu, 10 Aug 2023 02:58:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4RLs7T6cxxz3Hl9; Thu, 10 Aug 2023 02:58:29 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1691636310; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0r/6Osx9CjbBTJJT/iK6Vs5bLc5/2ZaRFRfXtz2Mjdo=; b=yCWnf0vE9oE+bIKVcbEK8xz/EfQ1SVVZqoAbI2aJp1sChsGU0J7PGyX7KtZhJjlBfxBtyH wbMJO/teO7HaloF/Y6umj53HdUIp+yKiMJaJHzA/LhE89j97uxbUdvZO3cCsIAV9EcSdC6 8dIdWbf5zKdOoifMMb07qnWwhsiLXpR5ZTQMBY1X2iOXunSuirr9O5jRqmnKcFFj6POhfg Xm7mPvQ9UZt3aeJFgLhaFd8pH98R0VpekfkOuunPp9pOQYAPk7jZmygivvrNW/wcGS3lH0 CMBMEeUP/gDffBn67CC51PW0CPpNJi471KA/8yMkipaOKJYLLwAxq3H6tx+1qg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1691636309; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0r/6Osx9CjbBTJJT/iK6Vs5bLc5/2ZaRFRfXtz2Mjdo=; b=u6R1uqSmPzt3xgdm97ktVT8dVdC+k3hy8bNeAMnC6PIlBC76X9fDB2j462iqBMlzz0HnNk r22xq2HgDAgr+H4HhWbkpW/VMzU4WLalT4H7CtlvuyxU9MDL4G8YH+0Nlz332Vl+y3hX/I hpsTrtWbpXFV6X6iZnK9qaHJs+akE9ZaFIaBKdD6HaIAUlmdCrlK9WN7fSDqYyw4VM7YMo rcuWwkKmfM6+Dfs2WePsxptYG39YdgJ8njSizx2rKRLSxzOSLXodcrywB3QH63P5S9FtSB odl54vVDRImWSppBmxAJWcoPY43RYenUrDo22T5MDYmYdp960DOmhQhmhR6ViQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1691636309; a=rsa-sha256; cv=none; b=XmQ3jwD+VKTIbYpsVIJ9+Wr4W6SSaAScJMqySFM+KDomV39ywzokCyA5TVyy748UotqtOO TlEcM4Cd9pSIa2ei7f9tecQSKWTb8cYxtLFESR6OeQ2mk0dAiRkhSnd1pAzdES2cFKmXkw 67erpafFhJmXw9N62QR7VrbVReGvTI854+CsTAImmCj2eziYCuQHDggm8WsBDo4QEC/ykf Xglc+snkRur46AU/75kER0xdDTuZf0tkpMzWSsIK+ERE1xiA4huFaIEG/in55NG6qDl9Xd Dxw6RRfjc4E/P42ScxB3AGg2MMmiklb8HrBZtKfyCwgCUsZM0kFWuoDxFNvCxg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4RLs7T5Q39zgVd; Thu, 10 Aug 2023 02:58:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 37A2wTg5074282; Thu, 10 Aug 2023 02:58:29 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 37A2wThC074279; Thu, 10 Aug 2023 02:58:29 GMT (envelope-from git) Date: Thu, 10 Aug 2023 02:58:29 GMT Message-Id: <202308100258.37A2wThC074279@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 6fe5d4d8c3c7 - stable/13 - Fixes for bugs in sinpi/cospi/tanpi List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 6fe5d4d8c3c7cf3a2a81f38300766a733029c763 Auto-Submitted: auto-generated The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=6fe5d4d8c3c7cf3a2a81f38300766a733029c763 commit 6fe5d4d8c3c7cf3a2a81f38300766a733029c763 Author: Steve Kargl AuthorDate: 2023-07-31 22:34:48 +0000 Commit: Konstantin Belousov CommitDate: 2023-08-10 02:57:29 +0000 Fixes for bugs in sinpi/cospi/tanpi PR: 272742 (cherry picked from commit 2d3b0a687b910c84606e4bc36176945ad5c60406) --- lib/msun/ld128/s_cospil.c | 50 ++++++++++++++++++++---------------------- lib/msun/ld128/s_sinpil.c | 38 ++++++++++++-------------------- lib/msun/ld128/s_tanpil.c | 39 ++++++++++++++++----------------- lib/msun/ld80/s_cospil.c | 22 ++++++------------- lib/msun/ld80/s_sinpil.c | 16 +++----------- lib/msun/ld80/s_tanpil.c | 34 ++++++++++++----------------- lib/msun/src/math_private.h | 53 +++++++++++++++++++++++++++++++++++++++++++++ lib/msun/src/s_cospi.c | 20 +++++------------ lib/msun/src/s_cospif.c | 16 ++++++-------- lib/msun/src/s_sinpi.c | 13 ++--------- lib/msun/src/s_sinpif.c | 10 +++------ lib/msun/src/s_tanpi.c | 41 +++++++++++++++++------------------ lib/msun/src/s_tanpif.c | 24 ++++++++++---------- 13 files changed, 183 insertions(+), 193 deletions(-) diff --git a/lib/msun/ld128/s_cospil.c b/lib/msun/ld128/s_cospil.c index 71acc4485f7b..b21f879c3e84 100644 --- a/lib/msun/ld128/s_cospil.c +++ b/lib/msun/ld128/s_cospil.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017-2021 Steven G. Kargl + * Copyright (c) 2017-2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +28,7 @@ * See ../src/s_cospi.c for implementation details. */ +#include "fpmath.h" #include "math.h" #include "math_private.h" @@ -46,8 +47,7 @@ volatile static const double vzero = 0; long double cospil(long double x) { - long double ax, c, xf; - uint32_t ix; + long double ai, ar, ax, c; ax = fabsl(x); @@ -72,41 +72,37 @@ cospil(long double x) } if (ax < 0x1p112) { - /* Split x = n + r with 0 <= r < 1. */ - xf = (ax + 0x1p112L) - 0x1p112L; /* Integer part */ - ax -= xf; /* Remainder */ - if (ax < 0) { - ax += 1; - xf -= 1; - } + /* Split ax = ai + ar with 0 <= ar < 1. */ + FFLOORL128(ax, ai, ar); - if (ax < 0.5) { - if (ax < 0.25) - c = ax == 0 ? 1 : __kernel_cospil(ax); + if (ar < 0.5) { + if (ar < 0.25) + c = ar == 0 ? 1 : __kernel_cospil(ar); else - c = __kernel_sinpil(0.5 - ax); + c = __kernel_sinpil(0.5 - ar); } else { - if (ax < 0.75) { - if (ax == 0.5) + if (ar < 0.75) { + if (ar == 0.5) return (0); - c = -__kernel_sinpil(ax - 0.5); + c = -__kernel_sinpil(ar - 0.5); } else - c = -__kernel_cospil(1 - ax); + c = -__kernel_cospil(1 - ar); } - - if (xf > 0x1p64) - xf -= 0x1p64; - if (xf > 0x1p32) - xf -= 0x1p32; - ix = (uint32_t)xf; - return (ix & 1 ? -c : c); + return (fmodl(ai, 2.L) == 0 ? c : -c); } if (isinf(x) || isnan(x)) return (vzero / vzero); /* - * |x| >= 0x1p112 is always an even integer, so return 1. + * For |x| >= 0x1p113, it is always an even integer, so return 1. */ - return (1); + if (ax >= 0x1p113) + return (1); + /* + * For 0x1p112 <= |x| < 0x1p113 need to determine if x is an even + * or odd integer to return 1 or -1. + */ + + return (fmodl(ax, 2.L) == 0 ? 1 : -1); } diff --git a/lib/msun/ld128/s_sinpil.c b/lib/msun/ld128/s_sinpil.c index cdfa2bcac3ef..c8c205449557 100644 --- a/lib/msun/ld128/s_sinpil.c +++ b/lib/msun/ld128/s_sinpil.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017-2021 Steven G. Kargl + * Copyright (c) 2017-2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +28,7 @@ * See ../src/s_sinpi.c for implementation details. */ +#include "fpmath.h" #include "math.h" #include "math_private.h" @@ -46,8 +47,7 @@ volatile static const double vzero = 0; long double sinpil(long double x) { - long double ax, hi, lo, s, xf, xhi, xlo; - uint32_t ix; + long double ai, ar, ax, hi, lo, s, xhi, xlo; ax = fabsl(x); @@ -78,35 +78,25 @@ sinpil(long double x) } if (ax < 0x1p112) { - /* Split x = n + r with 0 <= r < 1. */ - xf = (ax + 0x1p112L) - 0x1p112L; /* Integer part */ - ax -= xf; /* Remainder */ - if (ax < 0) { - ax += 1; - xf -= 1; - } + /* Split ax = ai + ar with 0 <= ar < 1. */ + FFLOORL128(ax, ai, ar); - if (ax == 0) { + if (ar == 0) { s = 0; } else { - if (ax < 0.5) { - if (ax <= 0.25) - s = __kernel_sinpil(ax); + if (ar < 0.5) { + if (ar <= 0.25) + s = __kernel_sinpil(ar); else - s = __kernel_cospil(0.5 - ax); + s = __kernel_cospil(0.5 - ar); } else { - if (ax < 0.75) - s = __kernel_cospil(ax - 0.5); + if (ar < 0.75) + s = __kernel_cospil(ar - 0.5); else - s = __kernel_sinpil(1 - ax); + s = __kernel_sinpil(1 - ar); } - if (xf > 0x1p64) - xf -= 0x1p64; - if (xf > 0x1p32) - xf -= 0x1p32; - ix = (uint32_t)xf; - if (ix & 1) s = -s; + s = fmodl(ai, 2.L) == 0 ? s : -s; } return (x < 0 ? -s : s); } diff --git a/lib/msun/ld128/s_tanpil.c b/lib/msun/ld128/s_tanpil.c index 90f4aea5c629..2d253bb9f478 100644 --- a/lib/msun/ld128/s_tanpil.c +++ b/lib/msun/ld128/s_tanpil.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017-2021 Steven G. Kargl + * Copyright (c) 2017-2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +28,7 @@ * See ../src/s_tanpi.c for implementation details. */ +#include "fpmath.h" #include "math.h" #include "math_private.h" @@ -69,8 +70,8 @@ volatile static const double vzero = 0; long double tanpil(long double x) { - long double ax, hi, lo, xf, t; - uint32_t ix; + long double ai, ar, ax, hi, lo, t; + double odd; ax = fabsl(x); @@ -88,27 +89,22 @@ tanpil(long double x) } t = __kernel_tanpil(ax); } else if (ax == 0.5) - return ((ax - ax) / (ax - ax)); + t = 1 / vzero; else t = -__kernel_tanpil(1 - ax); return (x < 0 ? -t : t); } - if (ix < 0x1p112) { - /* Split x = n + r with 0 <= r < 1. */ - xf = (ax + 0x1p112L) - 0x1p112L; /* Integer part */ - ax -= xf; /* Remainder */ - if (ax < 0) { - ax += 1; - xf -= 1; - } - - if (ax < 0.5) - t = ax == 0 ? 0 : __kernel_tanpil(ax); - else if (ax == 0.5) - return ((ax - ax) / (ax - ax)); + if (ax < 0x1p112) { + /* Split ax = ai + ar with 0 <= ar < 1. */ + FFLOORL128(ax, ai, ar); + odd = fmodl(ai, 2.L) == 0 ? 1 : -1; + if (ar < 0.5) + t = ar == 0 ? copysign(0., odd) : __kernel_tanpil(ar); + else if (ar == 0.5) + t = odd / vzero; else - t = -__kernel_tanpil(1 - ax); + t = -__kernel_tanpil(1 - ar); return (x < 0 ? -t : t); } @@ -117,7 +113,10 @@ tanpil(long double x) return (vzero / vzero); /* - * |x| >= 0x1p112 is always an integer, so return +-0. + * For 0x1p112 <= |x| < 0x1p113 need to determine if x is an even + * or odd integer to set t = +0 or -0. + * For |x| >= 0x1p113, it is always an even integer, so t = 0. */ - return (copysignl(0, x)); + t = fmodl(ax,2.L) == 0 ? 0 : copysign(0., -1.); + return (copysignl(t, x)); } diff --git a/lib/msun/ld80/s_cospil.c b/lib/msun/ld80/s_cospil.c index 199479e9eaf9..69620d2f2f33 100644 --- a/lib/msun/ld80/s_cospil.c +++ b/lib/msun/ld80/s_cospil.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017, 2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,18 +80,8 @@ cospil(long double x) RETURNI(c); } - if (ix < 0x403e) { /* 1 <= |x| < 0x1p63 */ - /* Determine integer part of ax. */ - j0 = ix - 0x3fff + 1; - if (j0 < 32) { - lx = (lx >> 32) << 32; - lx &= ~(((lx << 32)-1) >> j0); - } else { - m = (uint64_t)-1 >> (j0 + 1); - if (lx & m) lx &= ~m; - } - INSERT_LDBL80_WORDS(x, ix, lx); - + if (ix < 0x403e) { /* 1 <= |x| < 0x1p63 */ + FFLOORL80(x, j0, ix, lx); /* Integer part of ax. */ ax -= x; EXTRACT_LDBL80_WORDS(ix, lx, ax); @@ -123,7 +113,9 @@ cospil(long double x) RETURNI(vzero / vzero); /* - * |x| >= 0x1p63 is always an even integer, so return 1. + * For 0x1p63 <= |x| < 0x1p64 need to determine if x is an even + * or odd integer to return t = +1 or -1. + * For |x| >= 0x1p64, it is always an even integer, so t = 1. */ - RETURNI(1); + RETURNI(ix >= 0x403f ? 1 : ((lx & 1) ? -1 : 1)); } diff --git a/lib/msun/ld80/s_sinpil.c b/lib/msun/ld80/s_sinpil.c index 4cefa92352e1..7d9008f9e18f 100644 --- a/lib/msun/ld80/s_sinpil.c +++ b/lib/msun/ld80/s_sinpil.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017, 2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -88,18 +88,8 @@ sinpil(long double x) RETURNI((hx & 0x8000) ? -s : s); } - if (ix < 0x403e) { /* 1 <= |x| < 0x1p63 */ - /* Determine integer part of ax. */ - j0 = ix - 0x3fff + 1; - if (j0 < 32) { - lx = (lx >> 32) << 32; - lx &= ~(((lx << 32)-1) >> j0); - } else { - m = (uint64_t)-1 >> (j0 + 1); - if (lx & m) lx &= ~m; - } - INSERT_LDBL80_WORDS(x, ix, lx); - + if (ix < 0x403e) { /* 1 <= |x| < 0x1p63 */ + FFLOORL80(x, j0, ix, lx); /* Integer part of ax. */ ax -= x; EXTRACT_LDBL80_WORDS(ix, lx, ax); diff --git a/lib/msun/ld80/s_tanpil.c b/lib/msun/ld80/s_tanpil.c index 02451e562025..2d640413af6c 100644 --- a/lib/msun/ld80/s_tanpil.c +++ b/lib/msun/ld80/s_tanpil.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017, 2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -72,7 +72,7 @@ volatile static const double vzero = 0; long double tanpil(long double x) { - long double ax, hi, lo, t; + long double ax, hi, lo, odd, t; uint64_t lx, m; uint32_t j0; uint16_t hx, ix; @@ -98,31 +98,22 @@ tanpil(long double x) } t = __kernel_tanpil(ax); } else if (ax == 0.5) - RETURNI((ax - ax) / (ax - ax)); + t = 1 / vzero; else t = -__kernel_tanpil(1 - ax); RETURNI((hx & 0x8000) ? -t : t); } - if (ix < 0x403e) { /* 1 <= |x| < 0x1p63 */ - /* Determine integer part of ax. */ - j0 = ix - 0x3fff + 1; - if (j0 < 32) { - lx = (lx >> 32) << 32; - lx &= ~(((lx << 32)-1) >> j0); - } else { - m = (uint64_t)-1 >> (j0 + 1); - if (lx & m) lx &= ~m; - } - INSERT_LDBL80_WORDS(x, ix, lx); - + if (ix < 0x403e) { /* 1 <= |x| < 0x1p63 */ + FFLOORL80(x, j0, ix, lx); /* Integer part of ax. */ + odd = (uint64_t)x & 1 ? -1 : 1; ax -= x; EXTRACT_LDBL80_WORDS(ix, lx, ax); if (ix < 0x3ffe) /* |x| < 0.5 */ - t = ax == 0 ? 0 : __kernel_tanpil(ax); - else if (ax == 0.5) - RETURNI((ax - ax) / (ax - ax)); + t = ix == 0 ? copysignl(0, odd) : __kernel_tanpil(ax); + else if (ax == 0.5L) + t = odd / vzero; else t = -__kernel_tanpil(1 - ax); RETURNI((hx & 0x8000) ? -t : t); @@ -133,7 +124,10 @@ tanpil(long double x) RETURNI(vzero / vzero); /* - * |x| >= 0x1p63 is always an integer, so return +-0. + * For 0x1p63 <= |x| < 0x1p64 need to determine if x is an even + * or odd integer to set t = +0 or -0. + * For |x| >= 0x1p64, it is always an even integer, so t = 0. */ - RETURNI(copysignl(0, x)); + t = ix >= 0x403f ? 0 : (copysignl(0, (lx & 1) ? -1 : 1)); + RETURNI((hx & 0x8000) ? -t : t); } diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h index 429b9c70b215..814a05ebce67 100644 --- a/lib/msun/src/math_private.h +++ b/lib/msun/src/math_private.h @@ -688,6 +688,59 @@ irintl(long double x) } #endif +/* + * The following are fast floor macros for 0 <= |x| < 0x1p(N-1), where + * N is the precision of the type of x. These macros are used in the + * half-cycle trignometric functions (e.g., sinpi(x)). + */ +#define FFLOORF(x, j0, ix) do { \ + (j0) = (((ix) >> 23) & 0xff) - 0x7f; \ + (ix) &= ~(0x007fffff >> (j0)); \ + SET_FLOAT_WORD((x), (ix)); \ +} while (0) + +#define FFLOOR(x, j0, ix, lx) do { \ + (j0) = (((ix) >> 20) & 0x7ff) - 0x3ff; \ + if ((j0) < 20) { \ + (ix) &= ~(0x000fffff >> (j0)); \ + (lx) = 0; \ + } else { \ + (lx) &= ~((uint32_t)0xffffffff >> ((j0) - 20)); \ + } \ + INSERT_WORDS((x), (ix), (lx)); \ +} while (0) + +#define FFLOORL80(x, j0, ix, lx) do { \ + j0 = ix - 0x3fff + 1; \ + if ((j0) < 32) { \ + (lx) = ((lx) >> 32) << 32; \ + (lx) &= ~((((lx) << 32)-1) >> (j0)); \ + } else { \ + uint64_t _m; \ + _m = (uint64_t)-1 >> (j0); \ + if ((lx) & _m) (lx) &= ~_m; \ + } \ + INSERT_LDBL80_WORDS((x), (ix), (lx)); \ +} while (0) + +#define FFLOORL128(x, ai, ar) do { \ + union IEEEl2bits u; \ + uint64_t m; \ + int e; \ + u.e = (x); \ + e = u.bits.exp - 16383; \ + if (e < 48) { \ + m = ((1llu << 49) - 1) >> (e + 1); \ + u.bits.manh &= ~m; \ + u.bits.manl = 0; \ + } else { \ + m = (uint64_t)-1 >> (e - 48); \ + u.bits.manl &= ~m; \ + } \ + (ai) = u.e; \ + (ar) = (x) - (ai); \ +} while (0) + #ifdef DEBUG #if defined(__amd64__) || defined(__i386__) #define breakpoint() asm("int $3") diff --git a/lib/msun/src/s_cospi.c b/lib/msun/src/s_cospi.c index 2e2f92733a86..f97570dc8792 100644 --- a/lib/msun/src/s_cospi.c +++ b/lib/msun/src/s_cospi.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017, 2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -104,20 +104,10 @@ cospi(double x) } if (ix < 0x43300000) { /* 1 <= |x| < 0x1p52 */ - /* Determine integer part of ax. */ - j0 = ((ix >> 20) & 0x7ff) - 0x3ff; - if (j0 < 20) { - ix &= ~(0x000fffff >> j0); - lx = 0; - } else { - lx &= ~((uint32_t)0xffffffff >> (j0 - 20)); - } - INSERT_WORDS(x, ix, lx); - + FFLOOR(x, j0, ix, lx); /* Integer part of ax. */ ax -= x; EXTRACT_WORDS(ix, lx, ax); - if (ix < 0x3fe00000) { /* |x| < 0.5 */ if (ix < 0x3fd00000) /* |x| < 0.25 */ c = ix == 0 ? 1 : __kernel_cospi(ax); @@ -143,9 +133,11 @@ cospi(double x) return (vzero / vzero); /* - * |x| >= 0x1p52 is always an even integer, so return 1. + * For 0x1p52 <= |x| < 0x1p53 need to determine if x is an even + * or odd integer to return +1 or -1. + * For |x| >= 0x1p53, it is always an even integer, so return 1. */ - return (1); + return (ix < 0x43400000 ? ((lx & 1) ? -1 : 1) : 1); } #if LDBL_MANT_DIG == 53 diff --git a/lib/msun/src/s_cospif.c b/lib/msun/src/s_cospif.c index 4dd881395baf..44d19f165025 100644 --- a/lib/msun/src/s_cospif.c +++ b/lib/msun/src/s_cospif.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017,2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -71,12 +71,8 @@ cospif(float x) return (c); } - if (ix < 0x4b000000) { /* 1 <= |x| < 0x1p23 */ - /* Determine integer part of ax. */ - j0 = ((ix >> 23) & 0xff) - 0x7f; - ix &= ~(0x007fffff >> j0); - SET_FLOAT_WORD(x, ix); - + if (ix < 0x4b000000) { /* 1 <= |x| < 0x1p23 */ + FFLOORF(x, j0, ix); /* Integer part of ax. */ ax -= x; GET_FLOAT_WORD(ix, ax); @@ -103,7 +99,9 @@ cospif(float x) return (vzero / vzero); /* - * |x| >= 0x1p23 is always an even integer, so return 1. + * For 0x1p23 <= |x| < 0x1p24 need to determine if x is an even + * or odd integer to return +1 or -1. + * For |x| >= 0x1p24, it is always an even integer, so return 1. */ - return (1); + return (ix < 0x4b800000 ? ((ix & 1) ? -1 : 1) : 1); } diff --git a/lib/msun/src/s_sinpi.c b/lib/msun/src/s_sinpi.c index bc3759e567a3..8b388de863c3 100644 --- a/lib/msun/src/s_sinpi.c +++ b/lib/msun/src/s_sinpi.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017, 2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -118,16 +118,7 @@ sinpi(double x) } if (ix < 0x43300000) { /* 1 <= |x| < 0x1p52 */ - /* Determine integer part of ax. */ - j0 = ((ix >> 20) & 0x7ff) - 0x3ff; - if (j0 < 20) { - ix &= ~(0x000fffff >> j0); - lx = 0; - } else { - lx &= ~((uint32_t)0xffffffff >> (j0 - 20)); - } - INSERT_WORDS(x, ix, lx); - + FFLOOR(x, j0, ix, lx); /* Integer part of ax. */ ax -= x; EXTRACT_WORDS(ix, lx, ax); diff --git a/lib/msun/src/s_sinpif.c b/lib/msun/src/s_sinpif.c index c9f76f8a2358..21082dee7d9c 100644 --- a/lib/msun/src/s_sinpif.c +++ b/lib/msun/src/s_sinpif.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017,2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -81,12 +81,8 @@ sinpif(float x) return ((hx & 0x80000000) ? -s : s); } - if (ix < 0x4b000000) { /* 1 <= |x| < 0x1p23 */ - /* Determine integer part of ax. */ - j0 = ((ix >> 23) & 0xff) - 0x7f; - ix &= ~(0x007fffff >> j0); - SET_FLOAT_WORD(x, ix); - + if (ix < 0x4b000000) { /* 1 <= |x| < 0x1p23 */ + FFLOORF(x, j0, ix); /* Integer part of ax. */ ax -= x; GET_FLOAT_WORD(ix, ax); diff --git a/lib/msun/src/s_tanpi.c b/lib/msun/src/s_tanpi.c index f911d56156b3..cd00adbcb86e 100644 --- a/lib/msun/src/s_tanpi.c +++ b/lib/msun/src/s_tanpi.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017, 2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,11 +56,15 @@ * 5. Special cases: * * tanpi(+-0) = +-0 - * tanpi(+-n) = +-0, for positive integers n. + * tanpi(n) = +0 for positive even and negative odd integer n. + * tanpi(n) = -0 for positive odd and negative even integer n. * tanpi(+-n+1/4) = +-1, for positive integers n. - * tanpi(+-n+1/2) = NaN, for positive integers n. - * tanpi(+-inf) = NaN. Raises the "invalid" floating-point exception. - * tanpi(nan) = NaN. Raises the "invalid" floating-point exception. + * tanpi(n+1/2) = +inf and raises the FE_DIVBYZERO exception for + * even integers n. + * tanpi(n+1/2) = -inf and raises the FE_DIVBYZERO exception for + * odd integers n. + * tanpi(+-inf) = NaN and raises the FE_INVALID exception. + * tanpi(nan) = NaN and raises the FE_INVALID exception. */ #include @@ -106,7 +110,7 @@ volatile static const double vzero = 0; double tanpi(double x) { - double ax, hi, lo, t; + double ax, hi, lo, odd, t; uint32_t hx, ix, j0, lx; EXTRACT_WORDS(hx, lx, x); @@ -132,30 +136,22 @@ tanpi(double x) } t = __kernel_tanpi(ax); } else if (ax == 0.5) - return ((ax - ax) / (ax - ax)); + t = 1 / vzero; else t = - __kernel_tanpi(1 - ax); return ((hx & 0x80000000) ? -t : t); } if (ix < 0x43300000) { /* 1 <= |x| < 0x1p52 */ - /* Determine integer part of ax. */ - j0 = ((ix >> 20) & 0x7ff) - 0x3ff; - if (j0 < 20) { - ix &= ~(0x000fffff >> j0); - lx = 0; - } else { - lx &= ~(((uint32_t)(0xffffffff)) >> (j0 - 20)); - } - INSERT_WORDS(x,ix,lx); - + FFLOOR(x, j0, ix, lx); /* Integer part of ax. */ + odd = (uint64_t)x & 1 ? -1 : 1; ax -= x; EXTRACT_WORDS(ix, lx, ax); if (ix < 0x3fe00000) /* |x| < 0.5 */ - t = ax == 0 ? 0 : __kernel_tanpi(ax); + t = ix == 0 ? copysign(0, odd) : __kernel_tanpi(ax); else if (ax == 0.5) - return ((ax - ax) / (ax - ax)); + t = odd / vzero; else t = - __kernel_tanpi(1 - ax); @@ -167,9 +163,12 @@ tanpi(double x) return (vzero / vzero); /* - * |x| >= 0x1p52 is always an integer, so return +-0. + * For 0x1p52 <= |x| < 0x1p53 need to determine if x is an even + * or odd integer to set t = +0 or -0. + * For |x| >= 0x1p54, it is always an even integer, so t = 0. */ - return (copysign(0, x)); + t = ix >= 0x43400000 ? 0 : (copysign(0, (lx & 1) ? -1 : 1)); + return ((hx & 0x80000000) ? -t : t); } #if LDBL_MANT_DIG == 53 diff --git a/lib/msun/src/s_tanpif.c b/lib/msun/src/s_tanpif.c index 6d4b627d1cf9..12dd8f838976 100644 --- a/lib/msun/src/s_tanpif.c +++ b/lib/msun/src/s_tanpif.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017 Steven G. Kargl + * Copyright (c) 2017,2023 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -58,7 +58,7 @@ volatile static const float vzero = 0; float tanpif(float x) { - float ax, hi, lo, t; + float ax, hi, lo, odd, t; uint32_t hx, ix, j0; GET_FLOAT_WORD(hx, x); @@ -79,25 +79,22 @@ tanpif(float x) } t = __kernel_tanpif(ax); } else if (ix == 0x3f000000) - return ((ax - ax) / (ax - ax)); + t = 1 / vzero; else t = - __kernel_tanpif(1 - ax); return ((hx & 0x80000000) ? -t : t); } if (ix < 0x4b000000) { /* 1 <= |x| < 0x1p23 */ - /* Determine integer part of ax. */ - j0 = ((ix >> 23) & 0xff) - 0x7f; - ix &= ~(0x007fffff >> j0); - SET_FLOAT_WORD(x, ix); - + FFLOORF(x, j0, ix); /* Integer part of ax. */ + odd = (uint32_t)x & 1 ? -1 : 1; ax -= x; GET_FLOAT_WORD(ix, ax); if (ix < 0x3f000000) /* |x| < 0.5 */ - t = ix == 0 ? 0 : __kernel_tanpif(ax); + t = ix == 0 ? copysignf(0, odd) : __kernel_tanpif(ax); else if (ix == 0x3f000000) - return ((ax - ax) / (ax - ax)); + t = odd / vzero; else t = - __kernel_tanpif(1 - ax); return ((hx & 0x80000000) ? -t : t); @@ -108,7 +105,10 @@ tanpif(float x) return (vzero / vzero); /* - * |x| >= 0x1p23 is always an integer, so return +-0. + * For 0x1p23 <= |x| < 0x1p24 need to determine if x is an even + * or odd integer to set t = +0 or -0. + * For |x| >= 0x1p24, it is always an even integer, so t = 0. */ - return (copysignf(0, x)); + t = ix >= 0x4b800000 ? 0 : (copysignf(0, (ix & 1) ? -1 : 1)); + return ((hx & 0x80000000) ? -t : t); }