Date: Sat, 02 May 2026 14:56:15 +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: f62d826a6f5b - main - lib/msun: fmaximum_mag_num family. Tests and man page Message-ID: <69f6108f.472a8.610d749f@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=f62d826a6f5b9022b0cedfe22a698998ad9cb7f4 commit f62d826a6f5b9022b0cedfe22a698998ad9cb7f4 Author: Jesús Blázquez <jesuscblazquez@gmail.com> AuthorDate: 2026-04-21 17:17:00 +0000 Commit: Robert Clausecker <fuz@FreeBSD.org> CommitDate: 2026-05-02 14:50:13 +0000 lib/msun: fmaximum_mag_num family. Tests and man page Added the fmaximum_mag_num{,f,l} and fminimum_mag_num{,f,l} functions. PR: 294719 Reviewed by: fuz, kargl MFC after: 1 month --- lib/msun/Makefile | 18 ++++-- lib/msun/Symbol.map | 18 ++++-- lib/msun/man/fmaximum_mag.3 | 2 +- lib/msun/man/fmaximum_mag_num.3 | 109 ++++++++++++++++++++++++++++++++ lib/msun/src/math.h | 18 ++++-- lib/msun/src/s_fmaximum_mag_num.c | 88 ++++++++++++++++++++++++++ lib/msun/src/s_fmaximum_mag_numf.c | 84 ++++++++++++++++++++++++ lib/msun/src/s_fmaximum_mag_numl.c | 77 ++++++++++++++++++++++ lib/msun/src/s_fminimum_mag_num.c | 90 ++++++++++++++++++++++++++ lib/msun/src/s_fminimum_mag_numf.c | 85 +++++++++++++++++++++++++ lib/msun/src/s_fminimum_mag_numl.c | 79 +++++++++++++++++++++++ lib/msun/tests/fmaximum_fminimum_test.c | 28 +++++++- 12 files changed, 677 insertions(+), 19 deletions(-) diff --git a/lib/msun/Makefile b/lib/msun/Makefile index d61f4e9a1659..a9b07babc0a6 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -76,9 +76,11 @@ COMMON_SRCS= b_tgamma.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_fmaximum.c s_fmaximumf.c \ - s_fmaximum_mag.c s_fmaximum_magf.c s_fmaximum_num.c s_fmaximum_numf.c \ + s_fmaximum_mag.c s_fmaximum_magf.c s_fmaximum_mag_num.c \ + s_fmaximum_mag_numf.c s_fmaximum_num.c s_fmaximum_numf.c \ s_fmin.c s_fminf.c s_fminimum.c s_fminimumf.c \ - s_fminimum_mag.c s_fminimum_magf.c s_fminimum_num.c s_fminimum_numf.c \ + s_fminimum_mag.c s_fminimum_magf.c s_fminimum_mag_num.c \ + s_fminimum_mag_numf.c s_fminimum_num.c s_fminimum_numf.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 \ @@ -135,8 +137,10 @@ 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_fmaximuml.c s_fmaximum_magl.c s_fmaximum_numl.c \ - s_fminl.c s_fminimuml.c s_fminimum_magl.c s_fminimum_numl.c \ + s_fmaxl.c s_fmaximuml.c s_fmaximum_magl.c \ + s_fmaximum_numl.c s_fmaximum_mag_numl.c \ + s_fminl.c s_fminimuml.c s_fminimum_magl.c \ + s_fminimum_numl.c s_fminimum_mag_numl.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 \ @@ -182,7 +186,8 @@ MAN= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 \ exp.3 fabs.3 fdim.3 \ feclearexcept.3 feenableexcept.3 fegetenv.3 \ fegetround.3 fenv.3 floor.3 fma.3 \ - fmax.3 fmaximum.3 fmaximum_mag.3 fmaximum_num.3 fmod.3 \ + fmax.3 fmaximum.3 fmaximum_mag.3 \ + fmaximum_mag_num.3 fmaximum_num.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 \ @@ -242,6 +247,9 @@ MLINKS+=fmaximum.3 fmaximumf.3 fmaximum.3 fmaximuml.3 \ MLINKS+=fmaximum_mag.3 fmaximum_magf.3 fmaximum_mag.3 fmaximum_magl.3 \ fmaximum_mag.3 fminimum_mag.3 fmaximum_mag.3 fminimum_magf.3 \ fmaximum_mag.3 fminimum_magl.3 +MLINKS+=fmaximum_mag_num.3 fmaximum_mag_numf.3 fmaximum_mag_num.3 fmaximum_mag_numl.3 \ + fmaximum_mag_num.3 fminimum_mag_num.3 fmaximum_mag_num.3 fminimum_mag_numf.3 \ + fmaximum_mag_num.3 fminimum_mag_numl.3 MLINKS+=fmaximum_num.3 fmaximum_numf.3 fmaximum_num.3 fmaximum_numl.3 \ fmaximum_num.3 fminimum_num.3 fmaximum_num.3 fminimum_numf.3 \ fmaximum_num.3 fminimum_numl.3 diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map index 35addfcee3d5..00222c960f80 100644 --- a/lib/msun/Symbol.map +++ b/lib/msun/Symbol.map @@ -323,19 +323,25 @@ FBSD_1.9 { fmaximum; fmaximumf; fmaximuml; - fminimum; - fminimumf; - fminimuml; fmaximum_mag; fmaximum_magf; fmaximum_magl; - fminimum_mag; - fminimum_magf; - fminimum_magl; + fmaximum_mag_num; + fmaximum_mag_numf; + fmaximum_mag_numl; fmaximum_num; fmaximum_numf; fmaximum_numl; + fminimum; + fminimumf; + fminimuml; + fminimum_mag; + fminimum_magf; + fminimum_magl; fminimum_num; fminimum_numf; fminimum_numl; + fminimum_mag_num; + fminimum_mag_numf; + fminimum_mag_numl; }; diff --git a/lib/msun/man/fmaximum_mag.3 b/lib/msun/man/fmaximum_mag.3 index f5e4c39f96ef..004f9d51daa2 100644 --- a/lib/msun/man/fmaximum_mag.3 +++ b/lib/msun/man/fmaximum_mag.3 @@ -84,7 +84,7 @@ These routines do not raise any floating-point exceptions. .Sh SEE ALSO .Xr fmax 3 , .Xr fmaximum 3 , -.Xr fmaximum_num 3 , +.Xr fmaximum_mag_num 3 , .Xr math 3 .Sh STANDARDS The diff --git a/lib/msun/man/fmaximum_mag_num.3 b/lib/msun/man/fmaximum_mag_num.3 new file mode 100644 index 000000000000..525822bcde27 --- /dev/null +++ b/lib/msun/man/fmaximum_mag_num.3 @@ -0,0 +1,109 @@ +.\" 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 3, 2026 +.Dt FMAXIMUM_MAG_NUM 3 +.Os +.Sh NAME +.Nm fmaximum_mag_num , +.Nm fmaximum_mag_numf , +.Nm fmaximum_mag_numl , +.Nm fminimum_mag_num , +.Nm fminimum_mag_numf , +.Nm fminimum_mag_numl +.Nd floating-point maximum and minimum magnitude number functions +.Sh LIBRARY +.Lb libm +.Sh SYNOPSIS +.In math.h +.Ft double +.Fn fmaximum_mag_num "double x" "double y" +.Ft float +.Fn fmaximum_mag_numf "float x" "float y" +.Ft "long double" +.Fn fmaximum_mag_numl "long double x" "long double y" +.Ft double +.Fn fminimum_mag_num "double x" "double y" +.Ft float +.Fn fminimum_mag_numf "float x" "float y" +.Ft "long double" +.Fn fminimum_mag_numl "long double x" "long double y" +.Sh DESCRIPTION +The +.Fn fmaximum_mag_num , +.Fn fmaximum_mag_numf , +and +.Fn fmaximum_mag_numl +functions determine the larger of the absolute values of +.Fa x +and +.Fa y , +and return the argument with the larger absolute value, +preferring a numeric value over an \*(Na. +If one argument is a numeric value and the other is an \*(Na, +the numeric value is returned. +If the absolute values are equal, the behavior is equivalent to calling the corresponding +.Fn fmaximum_num +function on the arguments. +.Pp +Likewise, the +.Fn fminimum_mag_num , +.Fn fminimum_mag_numf , +and +.Fn fminimum_mag_numl +functions determine the smaller of the absolute values of +.Fa x +and +.Fa y , +and return the argument with the smaller absolute value, +preferring a numeric value over an \*(Na. +If one argument is a numeric value and the other is an \*(Na, +the numeric value is returned. +If the absolute values are equal, the behavior is equivalent to calling the corresponding +.Fn fminimum_num +function on the arguments. +.Pp +If both arguments are \*(Nas, a quiet \*(Na is returned. +If either argument is a signaling \*(Na, an invalid exception is raised. +Otherwise, these routines do not raise any floating-point exceptions. +.Sh SEE ALSO +.Xr fmax 3 , +.Xr fmaximum 3 , +.Xr fmaximum_mag 3 , +.Xr fmaximum_num 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn fmaximum_mag_num , +.Fn fmaximum_mag_numf , +.Fn fmaximum_mag_numl , +.Fn fminimum_mag_num , +.Fn fminimum_mag_numf , +and +.Fn fminimum_mag_numl +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 853984953a91..9894401160d4 100644 --- a/lib/msun/src/math.h +++ b/lib/msun/src/math.h @@ -523,18 +523,24 @@ 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); double fmaximum_mag(double, double); float fmaximum_magf(float, float); long double fmaximum_magl(long double, long double); -double fminimum_mag(double, double); -float fminimum_magf(float, float); -long double fminimum_magl(long double, long double); +double fmaximum_mag_num(double, double); +float fmaximum_mag_numf(float, float); +long double fmaximum_mag_numl(long double, long double); double fmaximum_num(double, double); float fmaximum_numf(float, float); long double fmaximum_numl(long double, long double); +double fminimum(double, double); +float fminimumf(float, float); +long double fminimuml(long double, long double); +double fminimum_mag(double, double); +float fminimum_magf(float, float); +long double fminimum_magl(long double, long double); +double fminimum_mag_num(double, double); +float fminimum_mag_numf(float, float); +long double fminimum_mag_numl(long double, long double); double fminimum_num(double, double); float fminimum_numf(float, float); long double fminimum_numl(long double, long double); diff --git a/lib/msun/src/s_fmaximum_mag_num.c b/lib/msun/src/s_fmaximum_mag_num.c new file mode 100644 index 000000000000..fbb8ffbfc250 --- /dev/null +++ b/lib/msun/src/s_fmaximum_mag_num.c @@ -0,0 +1,88 @@ +/* + * 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 <stdbool.h> + +#include "fpmath.h" + +#ifdef USE_BUILTIN_FMAXIMUM_MAG_NUM +double +fmaximum_mag_num(double x, double y) +{ + return (__builtin_fmaximum_mag_num(x, y)); +} +#else +double +fmaximum_mag_num(double x, double y) +{ + union IEEEd2bits u[2]; + bool nan_x, nan_y; + + u[0].d = x; + u[1].d = y; + + nan_x = isnan(x); + nan_y = isnan(y); + + if (nan_x || nan_y) { + /* If both are NaN, adding returns qNaN */ + if (nan_x && nan_y) + return (x + y); + + /* force_except makes sure sNaN's raise exceptions */ + volatile double force_except = x + y; + force_except; + + if (nan_x) + return (y); + else + return (x); + } + + double ax = fabs(x); + double ay = fabs(y); + + if (ay > ax) + return (y); + if (ax > ay) + return (x); + + /* If magnitudes are equal, we break the tie with the sign */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[0].bits.sign].d); + + return (x); +} +#endif + +#if (LDBL_MANT_DIG == 53) +__weak_reference(fmaximum_mag_num, fmaximum_mag_numl); +#endif diff --git a/lib/msun/src/s_fmaximum_mag_numf.c b/lib/msun/src/s_fmaximum_mag_numf.c new file mode 100644 index 000000000000..18232ed5aba8 --- /dev/null +++ b/lib/msun/src/s_fmaximum_mag_numf.c @@ -0,0 +1,84 @@ +/* + * 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 <stdbool.h> + +#include "fpmath.h" + +#ifdef USE_BUILTIN_FMAXIMUM_MAG_NUMF +float +fmaximum_mag_numf(float x, float y) +{ + return (__builtin_fmaximum_mag_numf(x, y)); +} +#else +float +fmaximum_mag_numf(float x, float y) +{ + union IEEEf2bits u[2]; + bool nan_x, nan_y; + + u[0].f = x; + u[1].f = y; + + nan_x = isnan(x); + nan_y = isnan(y); + + if (nan_x || nan_y) { + /* If both are NaN, adding returns qNaN */ + if (nan_x && nan_y) + return (x + y); + + /* force_except makes sure sNaN's raise exceptions */ + volatile float force_except = x + y; + force_except; + + if (nan_x) + return (y); + else + return (x); + } + + float ax = fabsf(x); + float ay = fabsf(y); + + if (ay > ax) + return (y); + if (ax > ay) + return (x); + + /* If magnitudes are equal, we break the tie with the sign */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[0].bits.sign].f); + + return (x); +} +#endif + diff --git a/lib/msun/src/s_fmaximum_mag_numl.c b/lib/msun/src/s_fmaximum_mag_numl.c new file mode 100644 index 000000000000..eceee8059b03 --- /dev/null +++ b/lib/msun/src/s_fmaximum_mag_numl.c @@ -0,0 +1,77 @@ +/* + * 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 <stdbool.h> + +#include "fpmath.h" + +long double +fmaximum_mag_numl(long double x, long double y) +{ + union IEEEl2bits u[2]; + bool nan_x, nan_y; + + u[0].e = x; + mask_nbit_l(u[0]); + u[1].e = y; + mask_nbit_l(u[1]); + + nan_x = isnan(x); + nan_y = isnan(y); + + if (nan_x || nan_y) { + /* If both are NaN, adding returns qNaN */ + if (nan_x && nan_y) + return (x + y); + + /* force_except makes sure sNaN's raise exceptions */ + volatile long double force_except = x + y; + force_except; + + if (nan_x) + return (y); + else + return (x); + } + + long double ax = fabsl(x); + long double ay = fabsl(y); + + if (ay > ax) + return (y); + if (ax > ay) + return (x); + + /* If magnitudes are equal, we break the tie with the sign */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[0].bits.sign ? y : x); + + return (x); +} diff --git a/lib/msun/src/s_fminimum_mag_num.c b/lib/msun/src/s_fminimum_mag_num.c new file mode 100644 index 000000000000..b5f62837f1b4 --- /dev/null +++ b/lib/msun/src/s_fminimum_mag_num.c @@ -0,0 +1,90 @@ +/* + * 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 <stdbool.h> + +#include "fpmath.h" + +#ifdef USE_BUILTIN_FMINIMUM_MAG_NUM +double +fminimum_mag_num(double x, double y) +{ + return (__builtin_fminimum_mag_num(x, y)); +} +#else +double +fminimum_mag_num(double x, double y) +{ + union IEEEd2bits u[2]; + bool nan_x, nan_y; + + u[0].d = x; + u[1].d = y; + + nan_x = isnan(x); + nan_y = isnan(y); + + if (nan_x || nan_y) { + /* If both are NaN, adding returns qNaN */ + if (nan_x && nan_y) + return (x + y); + + /* force_except makes sure sNaN's raise exceptions */ + volatile double force_except = x + y; + force_except; + + if (nan_x) + return (y); + else + return (x); + } + + double ax = fabs(x); + double ay = fabs(y); + + if (ay < ax) + return (y); + if (ax < ay) + return (x); + + /* If magnitudes are equal, we break the tie with the sign */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[1].bits.sign].d); + + return (x); +} +#endif + +#if (LDBL_MANT_DIG == 53) +__weak_reference(fminimum_mag_num, fminimum_mag_numl); +#endif + + diff --git a/lib/msun/src/s_fminimum_mag_numf.c b/lib/msun/src/s_fminimum_mag_numf.c new file mode 100644 index 000000000000..b8cb31f2315a --- /dev/null +++ b/lib/msun/src/s_fminimum_mag_numf.c @@ -0,0 +1,85 @@ +/* + * 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 <stdbool.h> + +#include "fpmath.h" + +#ifdef USE_BUILTIN_FMINIMUM_MAG_NUMF +float +fminimum_mag_numf(float x, float y) +{ + return (__builtin_fminimum_mag_numf(x, y)); +} +#else +float +fminimum_mag_numf(float x, float y) +{ + union IEEEf2bits u[2]; + bool nan_x, nan_y; + + u[0].f = x; + u[1].f = y; + + nan_x = isnan(x); + nan_y = isnan(y); + + if (nan_x || nan_y) { + /* If both are NaN, adding returns qNaN */ + if (nan_x && nan_y) + return (x + y); + + /* force_except makes sure sNaN's raise exceptions */ + volatile float force_except = x + y; + force_except; + + if (nan_x) + return (y); + else + return (x); + } + + float ax = fabsf(x); + float ay = fabsf(y); + + if (ay < ax) + return (y); + if (ax < ay) + return (x); + + /* If magnitudes are equal, we break the tie with the sign */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[1].bits.sign].f); + + return (x); +} +#endif + + diff --git a/lib/msun/src/s_fminimum_mag_numl.c b/lib/msun/src/s_fminimum_mag_numl.c new file mode 100644 index 000000000000..1d001e84b618 --- /dev/null +++ b/lib/msun/src/s_fminimum_mag_numl.c @@ -0,0 +1,79 @@ +/* + * 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 <stdbool.h> + +#include "fpmath.h" + +long double +fminimum_mag_numl(long double x, long double y) +{ + union IEEEl2bits u[2]; + bool nan_x, nan_y; + + u[0].e = x; + mask_nbit_l(u[0]); + u[1].e = y; + mask_nbit_l(u[1]); + + nan_x = isnan(x); + nan_y = isnan(y); + + if (nan_x || nan_y) { + /* If both are NaN, adding returns qNaN */ + if (nan_x && nan_y) + return (x + y); + + /* force_except makes sure sNaN's raise exceptions */ + volatile long double force_except = x + y; + force_except; + + if (nan_x) + return (y); + else + return (x); + } + + long double ax = fabsl(x); + long double ay = fabsl(y); + + if (ay < ax) + return (y); + if (ax < ay) + return (x); + + /* If magnitudes are equal, we break the tie with the sign */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[1].bits.sign ? y : x); + + return (x); +} + + diff --git a/lib/msun/tests/fmaximum_fminimum_test.c b/lib/msun/tests/fmaximum_fminimum_test.c index 4c8ec9a5b0e0..0d97c4be8d8c 100644 --- a/lib/msun/tests/fmaximum_fminimum_test.c +++ b/lib/msun/tests/fmaximum_fminimum_test.c @@ -27,7 +27,8 @@ /* * Tests for fmaximum{,f,l}(), fminimum{,f,l}(), fmaximum_mag{,f,l}, - * fminimum_mag{,f,l}, fmaximum_num{,f,l}, fminimum_num{,f,l} + * fminimum_mag{,f,l}, fmaximum_num{,f,l}, fminimum_num{,f,l}, + * fmaximum_mag_num{,f,l} and fminimum_mag_num{,f,l} */ #include <sys/cdefs.h> @@ -130,6 +131,30 @@ testall_num_r(long double big, long double small, int rmode) { TEST(fminimum_numl, long double, small, big, expected_min_num, rmode); } +static void +testall_mag_num_r(long double big, long double small, int rmode) { + long double expected_max_mag_num = isnan(big) ? small : big; + long double expected_min_mag_num = isnan(small) ? big : small; + + if (fabsl(small) > fabsl(big)) { + expected_max_mag_num = small; + expected_min_mag_num = big; + } + + TEST(fmaximum_mag_numf, float, big, small, expected_max_mag_num, rmode); + TEST(fmaximum_mag_numf, float, small, big, expected_max_mag_num, rmode); + TEST(fmaximum_mag_num, double, big, small, expected_max_mag_num, rmode); + TEST(fmaximum_mag_num, double, small, big, expected_max_mag_num, rmode); + TEST(fmaximum_mag_numl, long double, big, small, expected_max_mag_num, rmode); + TEST(fmaximum_mag_numl, long double, small, big, expected_max_mag_num, rmode); + TEST(fminimum_mag_numf, float, big, small, expected_min_mag_num, rmode); + TEST(fminimum_mag_numf, float, small, big, expected_min_mag_num, rmode); + TEST(fminimum_mag_num, double, big, small, expected_min_mag_num, rmode); + TEST(fminimum_mag_num, double, small, big, expected_min_mag_num, rmode); + TEST(fminimum_mag_numl, long double, big, small, expected_min_mag_num, rmode); + TEST(fminimum_mag_numl, long double, small, big, expected_min_mag_num, rmode); +} + /* * Test all the functions: fmaximumf, fmaximum, fmaximuml, fminimumf, fminimum, fminimuml * in all rounding modes and with the arguments in different orders. @@ -148,6 +173,7 @@ testall(long double big, long double small) testall_r(big, small, rmodes[i]); testall_mag_r(big, small, rmodes[i]); testall_num_r(big, small, rmodes[i]); + testall_mag_num_r(big, small, rmodes[i]); } }home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f6108f.472a8.610d749f>
