Date: Sat, 04 Apr 2026 16:53:00 +0000 From: Robert Clausecker <fuz@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: =?utf-8?Q?Jes=C3=BAs?= =?utf-8?Q?Bl=C3=A1zqu?=ez <jesuscblazquez@gmail.com> Subject: git: e55db843ef45 - main - lib/msun: Added fmaximum and fminimum family. Tests and man page Message-ID: <69d141ec.18aa8.1d64ada@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by fuz: URL: https://cgit.FreeBSD.org/src/commit/?id=e55db843ef45a8788f69e110d97210fb3968b92f commit e55db843ef45a8788f69e110d97210fb3968b92f Author: Jesús Blázquez <jesuscblazquez@gmail.com> AuthorDate: 2026-03-31 16:31:15 +0000 Commit: Robert Clausecker <fuz@FreeBSD.org> CommitDate: 2026-04-04 16:52:40 +0000 lib/msun: Added fmaximum and fminimum family. Tests and man page Starting from the existing fmax{,f,l} functions I've added the fmaximum family, which handles NaN according to the newest standard (propagating it). This commit is a PoC for GSoC 2026. Reviewed by: fuz, kargl MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D55834 --- lib/msun/Makefile | 15 ++- lib/msun/Symbol.map | 11 ++ lib/msun/man/fmaximum.3 | 103 +++++++++++++++++ lib/msun/src/math.h | 6 + lib/msun/src/s_fmaximum.c | 65 +++++++++++ lib/msun/src/s_fmaximumf.c | 60 ++++++++++ lib/msun/src/s_fmaximuml.c | 54 +++++++++ lib/msun/src/s_fminimum.c | 66 +++++++++++ lib/msun/src/s_fminimumf.c | 61 +++++++++++ lib/msun/src/s_fminimuml.c | 55 ++++++++++ lib/msun/tests/Makefile | 1 + lib/msun/tests/fmaximum_fminimum_test.c | 188 ++++++++++++++++++++++++++++++++ 12 files changed, 680 insertions(+), 5 deletions(-) diff --git a/lib/msun/Makefile b/lib/msun/Makefile index 24989749a502..5112337f6297 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -75,8 +75,9 @@ COMMON_SRCS= b_tgamma.c \ s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabsf.c s_fdim.c \ s_finite.c s_finitef.c \ s_floor.c s_floorf.c s_fma.c s_fmaf.c \ - s_fmax.c s_fmaxf.c s_fmin.c \ - s_fminf.c s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \ + s_fmax.c s_fmaxf.c s_fmaximum.c s_fmaximumf.c \ + s_fmin.c s_fminf.c s_fminimum.c s_fminimumf.c \ + s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \ s_ilogbl.c s_isfinite.c s_isnan.c s_isnormal.c \ s_llrint.c s_llrintf.c s_llround.c s_llroundf.c s_llroundl.c \ s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \ @@ -131,7 +132,8 @@ COMMON_SRCS+= b_tgammal.c catrigl.c \ s_asinhl.c s_atanl.c s_cbrtl.c s_ceill.c s_cexpl.c \ s_clogl.c s_cosl.c s_cospil.c s_cprojl.c \ s_csqrtl.c s_erfl.c s_exp2l.c s_expl.c s_floorl.c s_fmal.c \ - s_fmaxl.c s_fminl.c s_frexpl.c s_logbl.c s_logl.c s_nanl.c \ + s_fmaxl.c s_fmaximuml.c s_fminl.c s_fminimuml.c \ + s_frexpl.c s_logbl.c s_logl.c s_nanl.c \ s_nextafterl.c s_nexttoward.c s_remquol.c s_rintl.c s_roundl.c \ s_scalbnl.c s_sinl.c s_sincosl.c s_sinpil.c \ s_tanhl.c s_tanl.c s_tanpil.c s_truncl.c w_cabsl.c @@ -175,8 +177,8 @@ MAN= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 \ cpow.3 csqrt.3 erf.3 \ exp.3 fabs.3 fdim.3 \ feclearexcept.3 feenableexcept.3 fegetenv.3 \ - fegetround.3 fenv.3 floor.3 \ - fma.3 fmax.3 fmod.3 hypot.3 ieee.3 ieee_test.3 ilogb.3 j0.3 \ + fegetround.3 fenv.3 floor.3 fma.3 \ + fmax.3 fmaximum.3 fmod.3 hypot.3 ieee.3 ieee_test.3 ilogb.3 j0.3 \ lgamma.3 log.3 lrint.3 lround.3 math.3 nan.3 \ nextafter.3 remainder.3 rint.3 \ round.3 scalbn.3 signbit.3 sin.3 sincos.3 \ @@ -229,6 +231,9 @@ MLINKS+=floor.3 floorf.3 floor.3 floorl.3 MLINKS+=fma.3 fmaf.3 fma.3 fmal.3 MLINKS+=fmax.3 fmaxf.3 fmax.3 fmaxl.3 \ fmax.3 fmin.3 fmax.3 fminf.3 fmax.3 fminl.3 +MLINKS+=fmaximum.3 fmaximuml.3 fmaximum.3 fmaximumf.3 \ + fmaximum.3 fminimum.3 fmaximum.3 fminimumf.3 \ + fmaximum.3 fminimuml.3 MLINKS+=fmod.3 fmodf.3 fmod.3 fmodl.3 MLINKS+=hypot.3 cabs.3 hypot.3 cabsf.3 hypot.3 cabsl.3 \ hypot.3 hypotf.3 hypot.3 hypotl.3 diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map index 4d5a5e4d7e6e..932cc000fe52 100644 --- a/lib/msun/Symbol.map +++ b/lib/msun/Symbol.map @@ -316,3 +316,14 @@ FBSD_1.7 { tanpif; tanpil; }; + +/* First added in 16.0-CURRENT */ + +FBSD_1.9 { + fmaximum; + fmaximumf; + fmaximuml; + fminimum; + fminimumf; + fminimuml; +}; diff --git a/lib/msun/man/fmaximum.3 b/lib/msun/man/fmaximum.3 new file mode 100644 index 000000000000..bd301163a034 --- /dev/null +++ b/lib/msun/man/fmaximum.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2004 David Schultz <das@FreeBSD.org> +.\" Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 4, 2026 +.Dt FMAXIMUM 3 +.Os +.Sh NAME +.Nm fmaximum , +.Nm fmaximumf , +.Nm fmaximuml , +.Nm fminimum , +.Nm fminimumf , +.Nm fminimuml +.Nd floating-point maximum and minimum functions +.Sh LIBRARY +.Lb libm +.Sh SYNOPSIS +.In math.h +.Ft double +.Fn fmaximum "double x" "double y" +.Ft float +.Fn fmaximumf "float x" "float y" +.Ft "long double" +.Fn fmaximuml "long double x" "long double y" +.Ft double +.Fn fminimum "double x" "double y" +.Ft float +.Fn fminimumf "float x" "float y" +.Ft "long double" +.Fn fminimuml "long double x" "long double y" +.Sh DESCRIPTION +The +.Fn fmaximum , +.Fn fmaximumf , +and +.Fn fmaximuml +functions return the larger of +.Fa x +and +.Fa y , +and likewise, the +.Fn fminimum , +.Fn fminimumf , +and +.Fn fminimuml +functions return the smaller of +.Fa x +and +.Fa y . +They treat +.Li +0.0 +as being larger than +.Li -0.0 . +.Pp +Unlike the +.Xr fmax 3 +family of functions, which ignore an \*(Na, if either argument to +.Fn fmaximum +or +.Fn fminimum +is an \*(Na, then the result is an \*(Na. +These routines do not raise any floating-point exceptions. +.Sh SEE ALSO +.Xr fabs 3 , +.Xr fdim 3 , +.Xr fmax 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn fmaximum , +.Fn fmaximumf , +.Fn fmaximuml , +.Fn fminimum , +.Fn fminimumf , +and +.Fn fminimuml +functions conform to +.St -isoC-2023 . +.Sh HISTORY +These routines first appeared in +.Fx 16.0 . diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h index 25bd64e36a63..103b82c1cdf8 100644 --- a/lib/msun/src/math.h +++ b/lib/msun/src/math.h @@ -520,6 +520,12 @@ long double sinpil(long double); double tanpi(double); float tanpif(float); long double tanpil(long double); +double fmaximum(double, double); +float fmaximumf(float, float); +long double fmaximuml(long double, long double); +double fminimum(double, double); +float fminimumf(float, float); +long double fminimuml(long double, long double); #endif /* __ISO_C_VISIBLE >= 2023 */ __END_DECLS diff --git a/lib/msun/src/s_fmaximum.c b/lib/msun/src/s_fmaximum.c new file mode 100644 index 000000000000..f9e1998a84c2 --- /dev/null +++ b/lib/msun/src/s_fmaximum.c @@ -0,0 +1,65 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <float.h> +#include <math.h> + +#include "fpmath.h" + +#ifdef USE_BUILTIN_FMAXIMUM +double +fmaximum(double x, double y) +{ + return (__builtin_fmaximum(x, y)); +} +#else +double +fmaximum(double x, double y) +{ + union IEEEd2bits u[2]; + + u[0].d = x; + u[1].d = y; + + /* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */ + if ((u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0) || + (u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0)) + return (NAN); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[0].bits.sign].d); + + return (x > y ? x : y); +} +#endif + +#if (LDBL_MANT_DIG == 53) +__weak_reference(fmaximum, fmaximuml); +#endif diff --git a/lib/msun/src/s_fmaximumf.c b/lib/msun/src/s_fmaximumf.c new file mode 100644 index 000000000000..db4b96c14749 --- /dev/null +++ b/lib/msun/src/s_fmaximumf.c @@ -0,0 +1,60 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <math.h> + +#include "fpmath.h" + +#ifdef USE_BUILTIN_FMAXIMUMF +float +fmaximumf(float x, float y) +{ + return (__builtin_fmaximumf(x, y)); +} +#else +float +fmaximumf(float x, float y) +{ + union IEEEf2bits u[2]; + + u[0].f = x; + u[1].f = y; + + /* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */ + if ((u[0].bits.exp == 255 && u[0].bits.man != 0) || + (u[1].bits.exp == 255 && u[1].bits.man != 0)) + return (NAN); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[0].bits.sign].f); + + return (x > y ? x : y); +} +#endif diff --git a/lib/msun/src/s_fmaximuml.c b/lib/msun/src/s_fmaximuml.c new file mode 100644 index 000000000000..c849478cf05a --- /dev/null +++ b/lib/msun/src/s_fmaximuml.c @@ -0,0 +1,54 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <math.h> + +#include "fpmath.h" + +long double +fmaximuml(long double x, long double y) +{ + union IEEEl2bits u[2]; + + u[0].e = x; + mask_nbit_l(u[0]); + u[1].e = y; + mask_nbit_l(u[1]); + + /* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */ + if ((u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0) || + (u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0)) + return (NAN); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[0].bits.sign ? y : x); + + return (x > y ? x : y); +} diff --git a/lib/msun/src/s_fminimum.c b/lib/msun/src/s_fminimum.c new file mode 100644 index 000000000000..64c81b560626 --- /dev/null +++ b/lib/msun/src/s_fminimum.c @@ -0,0 +1,66 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <float.h> +#include <math.h> + +#include "fpmath.h" + +#ifdef USE_BUILTIN_FMINIMUM +double +fminimum(double x, double y) +{ + return (__builtin_fminimum(x, y)); +} +#else +double +fminimum(double x, double y) +{ + union IEEEd2bits u[2]; + + u[0].d = x; + u[1].d = y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0 || + u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0) + return (NAN); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[1].bits.sign].d); + + return (x < y ? x : y); +} +#endif + +#if (LDBL_MANT_DIG == 53) +__weak_reference(fminimum, fminimuml); +#endif + diff --git a/lib/msun/src/s_fminimumf.c b/lib/msun/src/s_fminimumf.c new file mode 100644 index 000000000000..d3978f576931 --- /dev/null +++ b/lib/msun/src/s_fminimumf.c @@ -0,0 +1,61 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <math.h> + +#include "fpmath.h" + +#ifdef USE_BUILTIN_FMINIMUMF +float +fminimumf(float x, float y) +{ + return (__builtin_fminimumf(x, y)); +} +#else +float +fminimumf(float x, float y) +{ + union IEEEf2bits u[2]; + + u[0].f = x; + u[1].f = y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 255 && u[0].bits.man != 0 || + u[1].bits.exp == 255 && u[1].bits.man != 0) + return (NAN); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[1].bits.sign].f); + + return (x < y ? x : y); +} +#endif + diff --git a/lib/msun/src/s_fminimuml.c b/lib/msun/src/s_fminimuml.c new file mode 100644 index 000000000000..e2c5527ee319 --- /dev/null +++ b/lib/msun/src/s_fminimuml.c @@ -0,0 +1,55 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <math.h> + +#include "fpmath.h" + +long double +fminimuml(long double x, long double y) +{ + union IEEEl2bits u[2]; + + u[0].e = x; + mask_nbit_l(u[0]); + u[1].e = y; + mask_nbit_l(u[1]); + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0 || + u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0) + return (NAN); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[1].bits.sign ? y : x); + + return (x < y ? x : y); +} + diff --git a/lib/msun/tests/Makefile b/lib/msun/tests/Makefile index d2a3ebffadb3..d723e0aaf656 100644 --- a/lib/msun/tests/Makefile +++ b/lib/msun/tests/Makefile @@ -58,6 +58,7 @@ ATF_TESTS_C+= exponential_test ATF_TESTS_C+= fenv_test ATF_TESTS_C+= fma_test ATF_TESTS_C+= fmaxmin_test +ATF_TESTS_C+= fmaximum_fminimum_test ATF_TESTS_C+= ilogb2_test ATF_TESTS_C+= invtrig_test ATF_TESTS_C+= invctrig_test diff --git a/lib/msun/tests/fmaximum_fminimum_test.c b/lib/msun/tests/fmaximum_fminimum_test.c new file mode 100644 index 000000000000..4641f80dfdad --- /dev/null +++ b/lib/msun/tests/fmaximum_fminimum_test.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2008 David Schultz <das@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Tests for fmaximum{,f,l}() and fminimum{,f,l}() + */ + +#include <sys/cdefs.h> +#include <fenv.h> +#include <float.h> +#include <math.h> + +#include "test-utils.h" + +#pragma STDC FENV_ACCESS ON + +/* + * Test whether func(x, y) has the expected result, and make sure no + * exceptions are raised. + */ +#define TEST(func, type, x, y, expected, rmode) do { \ + type __x = (x); /* convert before we clear exceptions */ \ + type __y = (y); \ + ATF_REQUIRE_EQ(0, feclearexcept(ALL_STD_EXCEPT)); \ + long double __result = func((__x), (__y)); \ + CHECK_FP_EXCEPTIONS_MSG(0, ALL_STD_EXCEPT, \ + #func "(%.20Lg, %.20Lg) rmode%d", (x), (y), rmode); \ + ATF_CHECK_MSG(fpequal_cs(__result, (expected), true), \ + #func "(%.20Lg, %.20Lg) rmode%d = %.20Lg, expected %.20Lg", \ + (x), (y), rmode, __result, (expected)); \ +} while (0) + +static void +testall_r(long double big, long double small, int rmode) +{ + long double expected_max, expected_min; + if (isnan(big) || isnan(small)) { + expected_max = big + small; + expected_min = expected_max; + } else { + expected_max = big; + expected_min = small; + } + + TEST(fmaximumf, float, big, small, expected_max, rmode); + TEST(fmaximumf, float, small, big, expected_max, rmode); + TEST(fmaximum, double, big, small, expected_max, rmode); + TEST(fmaximum, double, small, big, expected_max, rmode); + TEST(fmaximuml, long double, big, small, expected_max, rmode); + TEST(fmaximuml, long double, small, big, expected_max, rmode); + TEST(fminimumf, float, big, small, expected_min, rmode); + TEST(fminimumf, float, small, big, expected_min, rmode); + TEST(fminimum, double, big, small, expected_min, rmode); + TEST(fminimum, double, small, big, expected_min, rmode); + TEST(fminimuml, long double, big, small, expected_min, rmode); + TEST(fminimuml, long double, small, big, expected_min, rmode); +} + +/* + * Test all the functions: fmaximumf, fmaximum, fmaximuml, fminimumf, fminimum, fminimuml + * in all rounding modes and with the arguments in different orders. + * The input 'big' must be >= 'small'. + */ +static void +testall(long double big, long double small) +{ + static const int rmodes[] = { + FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO + }; + int i; + + for (i = 0; i < 4; i++) { + fesetround(rmodes[i]); + testall_r(big, small, rmodes[i]); + } +} + +ATF_TC_WITHOUT_HEAD(test1); +ATF_TC_BODY(test1, tc) +{ + testall(1.0, 0.0); +} + +ATF_TC_WITHOUT_HEAD(test2); +ATF_TC_BODY(test2, tc) +{ + testall(42.0, nextafterf(42.0, -INFINITY)); +} +ATF_TC_WITHOUT_HEAD(test3); +ATF_TC_BODY(test3, tc) +{ + testall(nextafterf(42.0, INFINITY), 42.0); +} + +ATF_TC_WITHOUT_HEAD(test4); +ATF_TC_BODY(test4, tc) +{ + testall(-5.0, -5.0); +} + +ATF_TC_WITHOUT_HEAD(test5); +ATF_TC_BODY(test5, tc) +{ + testall(-3.0, -4.0); +} + +ATF_TC_WITHOUT_HEAD(test6); +ATF_TC_BODY(test6, tc) +{ + testall(1.0, NAN); +} +ATF_TC_WITHOUT_HEAD(test7); +ATF_TC_BODY(test7, tc) +{ + testall(INFINITY, NAN); +} + +ATF_TC_WITHOUT_HEAD(test8); +ATF_TC_BODY(test8, tc) +{ + testall(INFINITY, 1.0); +} + +ATF_TC_WITHOUT_HEAD(test9); +ATF_TC_BODY(test9, tc) +{ + testall(-3.0, -INFINITY); +} + +ATF_TC_WITHOUT_HEAD(test10); +ATF_TC_BODY(test10, tc) +{ + testall(3.0, -INFINITY); +} + +ATF_TC_WITHOUT_HEAD(test11); +ATF_TC_BODY(test11, tc) +{ + testall(NAN, NAN); +} + +ATF_TC_WITHOUT_HEAD(test12); +ATF_TC_BODY(test12, tc) +{ + testall(0.0, -0.0); +} + + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, test1); + ATF_TP_ADD_TC(tp, test2); + ATF_TP_ADD_TC(tp, test3); + ATF_TP_ADD_TC(tp, test4); + ATF_TP_ADD_TC(tp, test5); + ATF_TP_ADD_TC(tp, test6); + ATF_TP_ADD_TC(tp, test7); + ATF_TP_ADD_TC(tp, test8); + ATF_TP_ADD_TC(tp, test9); + ATF_TP_ADD_TC(tp, test10); + ATF_TP_ADD_TC(tp, test11); + ATF_TP_ADD_TC(tp, test12); + + return (atf_no_error()); +}home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69d141ec.18aa8.1d64ada>
