History log of /freebsd-current/lib/msun/src/s_cospi.c
Revision Date Author Comments
# 2d3b0a68 31-Jul-2023 Steve Kargl <kargl@FreeBSD.org>

Fixes for bugs in sinpi/cospi/tanpi

patch to fix half-cycle trigonometric functions

Paul Zimmermann, a MPFR developer, contacted me about large errors in
the half-cycle trigonometric functions. I've have investigated these
issues and developed the attached patch. The float, double, and ld80
(long double) changes have been tested.

Caveat emptor: The ld128 changes have not been compiled. The ld128
changes have not been tested. I do not have access to a system that
uses ld128 floating point.

Here is an itemized list of changes:

* lib/msun/src/math_private.h:
. Add fast floor macros to compute the integer part of |x| for
0 <= |x| 01xp(N-1), where N is the precision of the type of x.
These macros are used in the half-cycle trigonometric functions
(e.g., sinpi(x)).
. The FFLOOR80 macros is used with the Intel 80-bit extended double
functions. This macors corrects an off-by-one error, which led to
enormous error for |x| > 0x1p32.

* lib/msun/src/s_cospif.c:
* lib/msun/src/s_cospi.c:
* lib/msun/ld80/s_cospil.c:
. Update Copyright years.
. Use FFLOOR*() macro to get integer part of |x|.
. Correct handle the range 0x1p(N-1) <= |x| < 0x1pN. Here, one needs
to determine if the integral value of |x| is even or odd to choose
+1 or -1. If |x| >= 0x1pN, always return +1.

* lib/msun/src/s_sinpif.c:
* lib/msun/src/s_sinpi.c:
* lib/msun/ld80/s_sinpil.c:
. Update Copyright years.
. Use FFLOOR*() macro to get integer part of |x|.

* lib/msun/src/s_tanpif.c:
* lib/msun/src/s_tanpi.c:
* lib/msun/ld80/s_tanpil.c:
. Update Copyright years.
. For +-0.5, return +-inf. Previously, tanpi[fl]() returned an NaN.
. Use FFLOOR*() to get integer part of |x|. Need to determine if the
integer part is even or odd. This is used to set +-0 for |x|
integral
and +-inf for (n+1/2).
. For 0x1p(N-1) <= |x| < 0x1pN need to determine if x is an even or
odd
integer to select +0 or -0. For |x| >= 0x1pN, it is always an even
integer, select 0.
. Note, tanpi[fl](x) is an odd function, so one needs to consider
tanpi[fl](-|x|) = - tanpi[fl](|x|).

* lib/msun/ld128/s_cospil.c:
* lib/msun/ld128/s_sinpil.c:
* lib/msun/ld128/s_tanpil.c:
. Update Copyright years.
. These routines use an FFLOOR128 macros, which likely should be
replaced by a bit twiddling algorithm.
. The same considerations above are applied to 0x1p112 <= |x| <
0x1p113,
and |x| >= 0x1p113 cases.
. Note, even and odd determination used fmodl(x,2.), which is likely
slow.

PR: 272742
MFC after: 1 week


# be4c7f27 16-Jul-2023 Steve Kargl <kargl@FreeBSD.org>

libm: correctly test for for NaN and Infinity in sinpi(), cospi(), and tanpi()

The current versions of lib/msun/src/s_cospi.c, s_sinpi.c and s_tanpi.c
all exhibit the same defect. After checking for various numeric ranges,
they check to see whether the input argument is a NaN or an Infinity.
However, the code uses a value of 0x7f80000 instead of the correct value
of 0x7ff00000.

If you review s_cospif.c, s_sinpif.c, and s_tanpif.c, you will see that
the equivalent statements in these functions are accurate and have
appropriate source comments.

The impact of these defects is to flag some valid input values as
invalid and raise a pole error (divide by zero).

Reported by: Paul Green <Paul.Green@stratus.com>
PR: 272539
MFC after: 1 week


# 3bfc8376 28-Oct-2021 Steve Kargl <kargl@FreeBSD.org>

sinpi,cospi,tanpi: float.h needed for week reference

The patch fixes the omission of '#include <float.h>', which is needed for
the weak reference on systems with LDBL_MANT_DIG == DBL_MANT_DIG.

PR: 218514
MFC after: 1 week


# dce5f3ab 25-Oct-2021 Steve Kargl <kargl@FreeBSD.org>

[LIBM] implementations of sinpi[fl], cospi[fl], and tanpi[fl]

Both IEEE-754 2008 and ISO/IEC TS 18661-4 define the half-cycle
trignometric functions cospi, sinpi, and tanpi. The attached
patch implements cospi[fl], sinpi[fl], and tanpi[fl]. Limited
testing on the cospi and sinpi reveal a max ULP less than 0.89;
while tanpi is more problematic with a max ULP less than 2.01
in the interval [0,0.5]. The algorithms used in these functions
are documented in {ks}_cospi.c, {ks}_sinpi.c, and s_tanpi.c.

Note. I no longer have access to a system with ld128 and
adequate support to compile and test the ld128 implementations
of these functions. Given the almost complete lack of input from
others on improvements to libm, I doubt that anyone cares. If
someone does care, the ld128 files contain a number of FIXME comments,
and in particular, while the polynomial coefficients are given
I did not update the polynomial algorithms to properly use the
coefficients.

PR: 218514
MFC after: 2 weeks