Page MenuHomeFreeBSD

D56236.diff
No OneTemporary

D56236.diff

diff --git a/lib/msun/Makefile b/lib/msun/Makefile
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -76,7 +76,9 @@
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_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_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 \
@@ -133,7 +135,8 @@
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_fminl.c s_fminimuml.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_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 \
@@ -179,7 +182,8 @@
exp.3 fabs.3 fdim.3 \
feclearexcept.3 feenableexcept.3 fegetenv.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 \
+ fmax.3 fmaximum.3 fmaximum_mag.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 \
round.3 scalbn.3 signbit.3 sin.3 sincos.3 \
@@ -232,9 +236,15 @@
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 \
+MLINKS+=fmaximum.3 fmaximumf.3 fmaximum.3 fmaximuml.3 \
fmaximum.3 fminimum.3 fmaximum.3 fminimumf.3 \
fmaximum.3 fminimuml.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_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
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
--- a/lib/msun/Symbol.map
+++ b/lib/msun/Symbol.map
@@ -326,4 +326,16 @@
fminimum;
fminimumf;
fminimuml;
+ fmaximum_mag;
+ fmaximum_magf;
+ fmaximum_magl;
+ fminimum_mag;
+ fminimum_magf;
+ fminimum_magl;
+ fmaximum_num;
+ fmaximum_numf;
+ fmaximum_numl;
+ fminimum_num;
+ fminimum_numf;
+ fminimum_numl;
};
diff --git a/lib/msun/man/fmax.3 b/lib/msun/man/fmax.3
--- a/lib/msun/man/fmax.3
+++ b/lib/msun/man/fmax.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 6, 2026
+.Dd April 11, 2026
.Dt FMAX 3
.Os
.Sh NAME
@@ -93,6 +93,13 @@
.Li -0.0 .
This behavior is not specified by the C standard, is not portable,
and may not occur in light of compiler optimizations.
+Applications requiring specific handling of signed zeroes or
+.No \*(Na
+values are recommended to use
+.Xr fmaximum_num 3
+and
+.Xr fminimum_num 3
+instead, which have strictly defined behavior for these cases.
.Sh HISTORY
These routines first appeared in
.Fx 5.3 .
diff --git a/lib/msun/man/fmaximum.3 b/lib/msun/man/fmaximum.3
--- a/lib/msun/man/fmaximum.3
+++ b/lib/msun/man/fmaximum.3
@@ -83,9 +83,9 @@
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 fmaximum_num 3 ,
+.Xr fmaximum_mag 3 ,
.Xr math 3
.Sh STANDARDS
The
diff --git a/lib/msun/man/fmaximum.3 b/lib/msun/man/fmaximum_mag.3
copy from lib/msun/man/fmaximum.3
copy to lib/msun/man/fmaximum_mag.3
--- a/lib/msun/man/fmaximum.3
+++ b/lib/msun/man/fmaximum_mag.3
@@ -23,79 +23,78 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 4, 2026
-.Dt FMAXIMUM 3
+.Dd April 3, 2026
+.Dt FMAXIMUM_MAG 3
.Os
.Sh NAME
-.Nm fmaximum ,
-.Nm fmaximumf ,
-.Nm fmaximuml ,
-.Nm fminimum ,
-.Nm fminimumf ,
-.Nm fminimuml
-.Nd floating-point maximum and minimum functions
+.Nm fmaximum_mag ,
+.Nm fmaximum_magf ,
+.Nm fmaximum_magl ,
+.Nm fminimum_mag ,
+.Nm fminimum_magf ,
+.Nm fminimum_magl
+.Nd floating-point maximum and minimum magnitude functions
.Sh LIBRARY
.Lb libm
.Sh SYNOPSIS
.In math.h
.Ft double
-.Fn fmaximum "double x" "double y"
+.Fn fmaximum_mag "double x" "double y"
.Ft float
-.Fn fmaximumf "float x" "float y"
+.Fn fmaximum_magf "float x" "float y"
.Ft "long double"
-.Fn fmaximuml "long double x" "long double y"
+.Fn fmaximum_magl "long double x" "long double y"
.Ft double
-.Fn fminimum "double x" "double y"
+.Fn fminimum_mag "double x" "double y"
.Ft float
-.Fn fminimumf "float x" "float y"
+.Fn fminimum_magf "float x" "float y"
.Ft "long double"
-.Fn fminimuml "long double x" "long double y"
+.Fn fminimum_magl "long double x" "long double y"
.Sh DESCRIPTION
The
-.Fn fmaximum ,
-.Fn fmaximumf ,
+.Fn fmaximum_mag ,
+.Fn fmaximum_magf ,
and
-.Fn fmaximuml
-functions return the larger of
+.Fn fmaximum_magl
+functions determine the larger of the absolute values of
.Fa x
and
.Fa y ,
-and likewise, the
-.Fn fminimum ,
-.Fn fminimumf ,
+and return the argument with the larger absolute value.
+If the absolute values are equal, the behavior is equivalent to calling the corresponding
+.Fn fmaximum
+function on the arguments.
+.Pp
+Likewise, the
+.Fn fminimum_mag ,
+.Fn fminimum_magf ,
and
-.Fn fminimuml
-functions return the smaller of
+.Fn fminimum_magl
+functions determine the smaller of the absolute values 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
+.Fa y ,
+and return the argument with the smaller absolute value.
+If the absolute values are equal, the behavior is equivalent to calling the corresponding
.Fn fminimum
-is an \*(Na, then the result is an \*(Na.
+function on the arguments.
+.Pp
+If either argument 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 fmaximum 3 ,
+.Xr fmaximum_num 3 ,
.Xr math 3
.Sh STANDARDS
The
-.Fn fmaximum ,
-.Fn fmaximumf ,
-.Fn fmaximuml ,
-.Fn fminimum ,
-.Fn fminimumf ,
+.Fn fmaximum_mag ,
+.Fn fmaximum_magf ,
+.Fn fmaximum_magl ,
+.Fn fminimum_mag ,
+.Fn fminimum_magf ,
and
-.Fn fminimuml
+.Fn fminimum_magl
functions conform to
.St -isoC-2023 .
.Sh HISTORY
diff --git a/lib/msun/man/fmaximum.3 b/lib/msun/man/fmaximum_num.3
copy from lib/msun/man/fmaximum.3
copy to lib/msun/man/fmaximum_num.3
--- a/lib/msun/man/fmaximum.3
+++ b/lib/msun/man/fmaximum_num.3
@@ -23,79 +23,89 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 4, 2026
-.Dt FMAXIMUM 3
+.Dd April 3, 2026
+.Dt FMAXIMUM_NUM 3
.Os
.Sh NAME
-.Nm fmaximum ,
-.Nm fmaximumf ,
-.Nm fmaximuml ,
-.Nm fminimum ,
-.Nm fminimumf ,
-.Nm fminimuml
-.Nd floating-point maximum and minimum functions
+.Nm fmaximum_num ,
+.Nm fmaximum_numf ,
+.Nm fmaximum_numl ,
+.Nm fminimum_num ,
+.Nm fminimum_numf ,
+.Nm fminimum_numl
+.Nd floating-point maximum and minimum number functions
.Sh LIBRARY
.Lb libm
.Sh SYNOPSIS
.In math.h
.Ft double
-.Fn fmaximum "double x" "double y"
+.Fn fmaximum_num "double x" "double y"
.Ft float
-.Fn fmaximumf "float x" "float y"
+.Fn fmaximum_numf "float x" "float y"
.Ft "long double"
-.Fn fmaximuml "long double x" "long double y"
+.Fn fmaximum_numl "long double x" "long double y"
.Ft double
-.Fn fminimum "double x" "double y"
+.Fn fminimum_num "double x" "double y"
.Ft float
-.Fn fminimumf "float x" "float y"
+.Fn fminimum_numf "float x" "float y"
.Ft "long double"
-.Fn fminimuml "long double x" "long double y"
+.Fn fminimum_numl "long double x" "long double y"
.Sh DESCRIPTION
The
-.Fn fmaximum ,
-.Fn fmaximumf ,
+.Fn fmaximum_num ,
+.Fn fmaximum_numf ,
and
-.Fn fmaximuml
-functions return the larger of
+.Fn fmaximum_numl
+functions determine the larger of
.Fa x
and
.Fa y ,
-and likewise, the
-.Fn fminimum ,
-.Fn fminimumf ,
+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 both arguments are numeric, the larger value is returned.
+If both arguments are \*(Nas, a quiet \*(Na is returned.
+For the purpose of these functions, positive zero is considered
+greater than negative zero.
+.Pp
+Likewise, the
+.Fn fminimum_num ,
+.Fn fminimum_numf ,
and
-.Fn fminimuml
-functions return the smaller of
+.Fn fminimum_numl
+functions determine the smaller of
.Fa x
and
-.Fa y .
-They treat
-.Li +0.0
-as being larger than
-.Li -0.0 .
+.Fa y ,
+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 both arguments are numeric, the smaller value is returned.
+If both arguments are \*(Nas, a quiet \*(Na is returned.
+For the purpose of these functions, negative zero is considered
+less than positive zero.
.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.
+Unlike with the
+.Xr fmaximum 3
+and
+.Xr fmaximum_mag 3
+families of functions, 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 fabs 3 ,
-.Xr fdim 3 ,
.Xr fmax 3 ,
+.Xr fmaximum 3 ,
+.Xr fmaximum_mag 3 ,
.Xr math 3
.Sh STANDARDS
The
-.Fn fmaximum ,
-.Fn fmaximumf ,
-.Fn fmaximuml ,
-.Fn fminimum ,
-.Fn fminimumf ,
+.Fn fmaximum_num ,
+.Fn fmaximum_numf ,
+.Fn fmaximum_numl ,
+.Fn fminimum_num ,
+.Fn fminimum_numf ,
and
-.Fn fminimuml
+.Fn fminimum_numl
functions conform to
.St -isoC-2023 .
.Sh HISTORY
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h
--- a/lib/msun/src/math.h
+++ b/lib/msun/src/math.h
@@ -526,6 +526,18 @@
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_num(double, double);
+float fmaximum_numf(float, float);
+long double fmaximum_numl(long double, long double);
+double fminimum_num(double, double);
+float fminimum_numf(float, float);
+long double fminimum_numl(long double, long double);
#endif /* __ISO_C_VISIBLE >= 2023 */
__END_DECLS
diff --git a/lib/msun/src/s_fminimum.c b/lib/msun/src/s_fmaximum_mag.c
copy from lib/msun/src/s_fminimum.c
copy to lib/msun/src/s_fmaximum_mag.c
--- a/lib/msun/src/s_fminimum.c
+++ b/lib/msun/src/s_fmaximum_mag.c
@@ -2,7 +2,6 @@
* 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
@@ -32,35 +31,43 @@
#include "fpmath.h"
-#ifdef USE_BUILTIN_FMINIMUM
+#ifdef USE_BUILTIN_FMAXIMUM_MAG
double
-fminimum(double x, double y)
+fmaximum_mag(double x, double y)
{
- return (__builtin_fminimum(x, y));
+ return (__builtin_fmaximum_mag(x, y));
}
#else
double
-fminimum(double x, double y)
+fmaximum_mag(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)
+ /* 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. */
+ 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 (u[u[0].bits.sign].d);
- return (x < y ? x : y);
+ return (x);
}
#endif
#if (LDBL_MANT_DIG == 53)
-__weak_reference(fminimum, fminimuml);
+__weak_reference(fmaximum_mag, fmaximum_magl);
#endif
diff --git a/lib/msun/src/s_fminimumf.c b/lib/msun/src/s_fmaximum_magf.c
copy from lib/msun/src/s_fminimumf.c
copy to lib/msun/src/s_fmaximum_magf.c
--- a/lib/msun/src/s_fminimumf.c
+++ b/lib/msun/src/s_fmaximum_magf.c
@@ -2,7 +2,6 @@
* 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
@@ -31,31 +30,39 @@
#include "fpmath.h"
-#ifdef USE_BUILTIN_FMINIMUMF
+#ifdef USE_BUILTIN_FMAXIMUM_MAGF
float
-fminimumf(float x, float y)
+fmaximum_magf(float x, float y)
{
- return (__builtin_fminimumf(x, y));
+ return (__builtin_fmaximum_magf(x, y));
}
#else
float
-fminimumf(float x, float y)
+fmaximum_magf(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)
+ /* 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. */
+ 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 (u[u[0].bits.sign].f);
- return (x < y ? x : y);
+ return (x);
}
#endif
diff --git a/lib/msun/src/s_fminimuml.c b/lib/msun/src/s_fmaximum_magl.c
copy from lib/msun/src/s_fminimuml.c
copy to lib/msun/src/s_fmaximum_magl.c
--- a/lib/msun/src/s_fminimuml.c
+++ b/lib/msun/src/s_fmaximum_magl.c
@@ -2,7 +2,6 @@
* 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
@@ -32,7 +31,7 @@
#include "fpmath.h"
long double
-fminimuml(long double x, long double y)
+fmaximum_magl(long double x, long double y)
{
union IEEEl2bits u[2];
@@ -41,15 +40,23 @@
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)
+ /* 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. */
+ 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 (u[0].bits.sign ? y : x);
- return (x < y ? x : y);
+ return (x);
}
diff --git a/lib/msun/src/s_fminimum.c b/lib/msun/src/s_fmaximum_num.c
copy from lib/msun/src/s_fminimum.c
copy to lib/msun/src/s_fmaximum_num.c
--- a/lib/msun/src/s_fminimum.c
+++ b/lib/msun/src/s_fmaximum_num.c
@@ -29,38 +29,46 @@
#include <float.h>
#include <math.h>
+#include <stdbool.h>
#include "fpmath.h"
-#ifdef USE_BUILTIN_FMINIMUM
+#ifdef USE_BUILTIN_FMAXIMUM_NUM
double
-fminimum(double x, double y)
+fmaximum_num(double x, double y)
{
- return (__builtin_fminimum(x, y));
+ return (__builtin_fmaximum_num(x, y));
}
#else
double
-fminimum(double x, double y)
+fmaximum_num(double x, double y)
{
union IEEEd2bits u[2];
+ bool nan_x, nan_y;
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);
+ nan_x = u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0;
+ nan_y = u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0;
+
+ if (nan_x || nan_y) {
+ /* These ternary conditionals force (x+y), so that sNaN's raise exceptions */
+ if (nan_x && nan_y)
+ return (x + y);
+ if (nan_x)
+ return ((x + y) != 0.0 ? y : y);
+ return ((x + y) != 0.0 ? x : x);
+ }
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
- return (u[u[1].bits.sign].d);
+ return (u[u[0].bits.sign].d);
- return (x < y ? x : y);
+ return (x > y ? x : y);
}
#endif
#if (LDBL_MANT_DIG == 53)
-__weak_reference(fminimum, fminimuml);
+__weak_reference(fmaximum_num, fmaximum_numl);
#endif
-
diff --git a/lib/msun/src/s_fminimumf.c b/lib/msun/src/s_fmaximum_numf.c
copy from lib/msun/src/s_fminimumf.c
copy to lib/msun/src/s_fmaximum_numf.c
--- a/lib/msun/src/s_fminimumf.c
+++ b/lib/msun/src/s_fmaximum_numf.c
@@ -28,34 +28,43 @@
*/
#include <math.h>
+#include <stdbool.h>
#include "fpmath.h"
-#ifdef USE_BUILTIN_FMINIMUMF
+#ifdef USE_BUILTIN_FMAXIMUM_NUMF
float
-fminimumf(float x, float y)
+fmaximum_numf(float x, float y)
{
- return (__builtin_fminimumf(x, y));
+ return (__builtin_fmaximum_numf(x, y));
}
#else
float
-fminimumf(float x, float y)
+fmaximum_numf(float x, float y)
{
union IEEEf2bits u[2];
+ bool nan_x, nan_y;
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);
+ nan_x = u[0].bits.exp == 255 && u[0].bits.man != 0;
+ nan_y = u[1].bits.exp == 255 && u[1].bits.man != 0;
+
+ if (nan_x || nan_y) {
+ /* These ternary conditionals force (x+y), so that sNaN's raise exceptions */
+ if (nan_x && nan_y)
+ return (x + y);
+ if (nan_x)
+ return ((x + y) != 0.0 ? y : y);
+ return ((x + y) != 0.0 ? x : x);
+ }
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
- return (u[u[1].bits.sign].f);
+ return (u[u[0].bits.sign].f);
- return (x < y ? x : y);
+ return (x > y ? x : y);
}
#endif
diff --git a/lib/msun/src/s_fminimuml.c b/lib/msun/src/s_fmaximum_numl.c
copy from lib/msun/src/s_fminimuml.c
copy to lib/msun/src/s_fmaximum_numl.c
--- a/lib/msun/src/s_fminimuml.c
+++ b/lib/msun/src/s_fmaximum_numl.c
@@ -28,28 +28,36 @@
*/
#include <math.h>
+#include <stdbool.h>
#include "fpmath.h"
long double
-fminimuml(long double x, long double y)
+fmaximum_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]);
- /* 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);
+ nan_x = u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0;
+ nan_y = u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0;
+
+ if (nan_x || nan_y) {
+ /* These ternary conditionals force (x+y), so that sNaN's raise exceptions */
+ if (nan_x && nan_y)
+ return (x + y);
+ if (nan_x)
+ return ((x + y) != 0.0 ? y : y);
+ return ((x + y) != 0.0 ? x : x);
+ }
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
- return (u[1].bits.sign ? y : x);
+ return (u[0].bits.sign ? y : x);
- return (x < y ? x : y);
+ return (x > y ? x : y);
}
-
diff --git a/lib/msun/src/s_fminimum.c b/lib/msun/src/s_fminimum.c
--- a/lib/msun/src/s_fminimum.c
+++ b/lib/msun/src/s_fminimum.c
@@ -47,7 +47,7 @@
u[0].d = x;
u[1].d = y;
- /* Check for NaNs to avoid raising spurious exceptions. */
+ /* 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);
diff --git a/lib/msun/src/s_fminimum.c b/lib/msun/src/s_fminimum_mag.c
copy from lib/msun/src/s_fminimum.c
copy to lib/msun/src/s_fminimum_mag.c
--- a/lib/msun/src/s_fminimum.c
+++ b/lib/msun/src/s_fminimum_mag.c
@@ -2,7 +2,6 @@
* 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
@@ -32,35 +31,44 @@
#include "fpmath.h"
-#ifdef USE_BUILTIN_FMINIMUM
+#ifdef USE_BUILTIN_FMINIMUM_MAG
double
-fminimum(double x, double y)
+fminimum_mag(double x, double y)
{
- return (__builtin_fminimum(x, y));
+ return (__builtin_fminimum_mag(x, y));
}
#else
double
-fminimum(double x, double y)
+fminimum_mag(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 ||
+ /* 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. */
+ 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 < y ? x : y);
+ return (x);
}
#endif
#if (LDBL_MANT_DIG == 53)
-__weak_reference(fminimum, fminimuml);
+__weak_reference(fminimum_mag, fminimum_magl);
#endif
+
diff --git a/lib/msun/src/s_fminimumf.c b/lib/msun/src/s_fminimum_magf.c
copy from lib/msun/src/s_fminimumf.c
copy to lib/msun/src/s_fminimum_magf.c
--- a/lib/msun/src/s_fminimumf.c
+++ b/lib/msun/src/s_fminimum_magf.c
@@ -2,7 +2,6 @@
* 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
@@ -31,31 +30,40 @@
#include "fpmath.h"
-#ifdef USE_BUILTIN_FMINIMUMF
+#ifdef USE_BUILTIN_FMINIMUM_MAGF
float
-fminimumf(float x, float y)
+fminimum_magf(float x, float y)
{
- return (__builtin_fminimumf(x, y));
+ return (__builtin_fminimum_magf(x, y));
}
#else
float
-fminimumf(float x, float y)
+fminimum_magf(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 ||
+ /* 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. */
+ 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 < y ? x : y);
+ return (x);
}
#endif
+
diff --git a/lib/msun/src/s_fminimuml.c b/lib/msun/src/s_fminimum_magl.c
copy from lib/msun/src/s_fminimuml.c
copy to lib/msun/src/s_fminimum_magl.c
--- a/lib/msun/src/s_fminimuml.c
+++ b/lib/msun/src/s_fminimum_magl.c
@@ -2,7 +2,6 @@
* 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
@@ -32,7 +31,7 @@
#include "fpmath.h"
long double
-fminimuml(long double x, long double y)
+fminimum_magl(long double x, long double y)
{
union IEEEl2bits u[2];
@@ -41,15 +40,24 @@
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 ||
+ /* 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. */
+ 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 < y ? x : y);
+ return (x);
}
+
diff --git a/lib/msun/src/s_fminimum.c b/lib/msun/src/s_fminimum_num.c
copy from lib/msun/src/s_fminimum.c
copy to lib/msun/src/s_fminimum_num.c
--- a/lib/msun/src/s_fminimum.c
+++ b/lib/msun/src/s_fminimum_num.c
@@ -29,28 +29,37 @@
#include <float.h>
#include <math.h>
+#include <stdbool.h>
#include "fpmath.h"
-#ifdef USE_BUILTIN_FMINIMUM
+#ifdef USE_BUILTIN_FMINIMUM_NUM
double
-fminimum(double x, double y)
+fminimum_num(double x, double y)
{
- return (__builtin_fminimum(x, y));
+ return (__builtin_fminimum_num(x, y));
}
#else
double
-fminimum(double x, double y)
+fminimum_num(double x, double y)
{
union IEEEd2bits u[2];
+ bool nan_x, nan_y;
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);
+ nan_x = u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0;
+ nan_y = u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0;
+
+ if (nan_x || nan_y) {
+ /* These ternary conditionals force (x+y), so that sNaN's raise exceptions */
+ if (nan_x && nan_y)
+ return (x + y);
+ if (nan_x)
+ return ((x + y) != 0.0 ? y : y);
+ return ((x + y) != 0.0 ? x : x);
+ }
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
@@ -61,6 +70,7 @@
#endif
#if (LDBL_MANT_DIG == 53)
-__weak_reference(fminimum, fminimuml);
+__weak_reference(fminimum_num, fminimum_numl);
#endif
+
diff --git a/lib/msun/src/s_fminimumf.c b/lib/msun/src/s_fminimum_numf.c
copy from lib/msun/src/s_fminimumf.c
copy to lib/msun/src/s_fminimum_numf.c
--- a/lib/msun/src/s_fminimumf.c
+++ b/lib/msun/src/s_fminimum_numf.c
@@ -28,28 +28,37 @@
*/
#include <math.h>
+#include <stdbool.h>
#include "fpmath.h"
-#ifdef USE_BUILTIN_FMINIMUMF
+#ifdef USE_BUILTIN_FMINIMUM_NUMF
float
-fminimumf(float x, float y)
+fminimum_numf(float x, float y)
{
- return (__builtin_fminimumf(x, y));
+ return (__builtin_fminimum_numf(x, y));
}
#else
float
-fminimumf(float x, float y)
+fminimum_numf(float x, float y)
{
union IEEEf2bits u[2];
+ bool nan_x, nan_y;
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);
+ nan_x = u[0].bits.exp == 255 && u[0].bits.man != 0;
+ nan_y = u[1].bits.exp == 255 && u[1].bits.man != 0;
+
+ if (nan_x || nan_y) {
+ /* These ternary conditionals force (x+y), so that sNaN's raise exceptions */
+ if (nan_x && nan_y)
+ return (x + y);
+ if (nan_x)
+ return ((x + y) != 0.0 ? y : y);
+ return ((x + y) != 0.0 ? x : x);
+ }
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
@@ -59,3 +68,4 @@
}
#endif
+
diff --git a/lib/msun/src/s_fminimuml.c b/lib/msun/src/s_fminimum_numl.c
copy from lib/msun/src/s_fminimuml.c
copy to lib/msun/src/s_fminimum_numl.c
--- a/lib/msun/src/s_fminimuml.c
+++ b/lib/msun/src/s_fminimum_numl.c
@@ -28,23 +28,32 @@
*/
#include <math.h>
+#include <stdbool.h>
#include "fpmath.h"
long double
-fminimuml(long double x, long double y)
+fminimum_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]);
- /* 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);
+ nan_x = u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0;
+ nan_y = u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0;
+
+ if (nan_x || nan_y) {
+ /* These ternary conditionals force (x+y), so that sNaN's raise exceptions */
+ if (nan_x && nan_y)
+ return (x + y);
+ if (nan_x)
+ return ((x + y) != 0.0 ? y : y);
+ return ((x + y) != 0.0 ? x : x);
+ }
/* Handle comparisons of signed zeroes. */
if (u[0].bits.sign != u[1].bits.sign)
@@ -53,3 +62,4 @@
return (x < y ? x : y);
}
+
diff --git a/lib/msun/src/s_fminimumf.c b/lib/msun/src/s_fminimumf.c
--- a/lib/msun/src/s_fminimumf.c
+++ b/lib/msun/src/s_fminimumf.c
@@ -46,7 +46,7 @@
u[0].f = x;
u[1].f = y;
- /* Check for NaNs to avoid raising spurious exceptions. */
+ /* 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);
diff --git a/lib/msun/src/s_fminimuml.c b/lib/msun/src/s_fminimuml.c
--- a/lib/msun/src/s_fminimuml.c
+++ b/lib/msun/src/s_fminimuml.c
@@ -41,7 +41,7 @@
u[1].e = y;
mask_nbit_l(u[1]);
- /* Check for NaNs to avoid raising spurious exceptions. */
+ /* 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);
diff --git a/lib/msun/tests/fmaximum_fminimum_test.c b/lib/msun/tests/fmaximum_fminimum_test.c
--- a/lib/msun/tests/fmaximum_fminimum_test.c
+++ b/lib/msun/tests/fmaximum_fminimum_test.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 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
@@ -25,7 +26,8 @@
*/
/*
- * Tests for fmaximum{,f,l}() and fminimum{,f,l}()
+ * Tests for fmaximum{,f,l}(), fminimum{,f,l}(), fmaximum_mag{,f,l},
+ * fminimum_mag{,f,l}, fmaximum_num{,f,l}, fminimum_num{,f,l}
*/
#include <sys/cdefs.h>
@@ -58,7 +60,7 @@
{
long double expected_max, expected_min;
if (isnan(big) || isnan(small)) {
- expected_max = big + small;
+ expected_max = NAN;
expected_min = expected_max;
} else {
expected_max = big;
@@ -79,6 +81,55 @@
TEST(fminimuml, long double, small, big, expected_min, rmode);
}
+static void
+testall_mag_r(long double big, long double small, int rmode) {
+ long double expected_max_mag, expected_min_mag;
+ if (isnan(big) || isnan(small)) {
+ expected_max_mag = NAN;
+ expected_min_mag = expected_max_mag;
+ } else {
+ if (fabsl(small) > fabsl(big)) {
+ expected_max_mag = small;
+ expected_min_mag = big;
+ } else {
+ expected_max_mag = big;
+ expected_min_mag = small;
+ }
+ }
+
+ TEST(fmaximum_magf, float, big, small, expected_max_mag, rmode);
+ TEST(fmaximum_magf, float, small, big, expected_max_mag, rmode);
+ TEST(fmaximum_mag, double, big, small, expected_max_mag, rmode);
+ TEST(fmaximum_mag, double, small, big, expected_max_mag, rmode);
+ TEST(fmaximum_magl, long double, big, small, expected_max_mag, rmode);
+ TEST(fmaximum_magl, long double, small, big, expected_max_mag, rmode);
+ TEST(fminimum_magf, float, big, small, expected_min_mag, rmode);
+ TEST(fminimum_magf, float, small, big, expected_min_mag, rmode);
+ TEST(fminimum_mag, double, big, small, expected_min_mag, rmode);
+ TEST(fminimum_mag, double, small, big, expected_min_mag, rmode);
+ TEST(fminimum_magl, long double, big, small, expected_min_mag, rmode);
+ TEST(fminimum_magl, long double, small, big, expected_min_mag, rmode);
+}
+
+static void
+testall_num_r(long double big, long double small, int rmode) {
+ long double expected_max_num = isnan(big) ? small : big;
+ long double expected_min_num = isnan(small) ? big : small;
+
+ TEST(fmaximum_numf, float, big, small, expected_max_num, rmode);
+ TEST(fmaximum_numf, float, small, big, expected_max_num, rmode);
+ TEST(fmaximum_num, double, big, small, expected_max_num, rmode);
+ TEST(fmaximum_num, double, small, big, expected_max_num, rmode);
+ TEST(fmaximum_numl, long double, big, small, expected_max_num, rmode);
+ TEST(fmaximum_numl, long double, small, big, expected_max_num, rmode);
+ TEST(fminimum_numf, float, big, small, expected_min_num, rmode);
+ TEST(fminimum_numf, float, small, big, expected_min_num, rmode);
+ TEST(fminimum_num, double, big, small, expected_min_num, rmode);
+ TEST(fminimum_num, double, small, big, expected_min_num, rmode);
+ TEST(fminimum_numl, long double, big, small, expected_min_num, rmode);
+ TEST(fminimum_numl, long double, small, big, expected_min_num, rmode);
+}
+
/*
* Test all the functions: fmaximumf, fmaximum, fmaximuml, fminimumf, fminimum, fminimuml
* in all rounding modes and with the arguments in different orders.
@@ -95,6 +146,8 @@
for (i = 0; i < 4; i++) {
fesetround(rmodes[i]);
testall_r(big, small, rmodes[i]);
+ testall_mag_r(big, small, rmodes[i]);
+ testall_num_r(big, small, rmodes[i]);
}
}
@@ -169,6 +222,24 @@
}
+ATF_TC_WITHOUT_HEAD(test13);
+ATF_TC_BODY(test13, tc)
+{
+ testall(2.0, -2.0);
+}
+
+ATF_TC_WITHOUT_HEAD(test14);
+ATF_TC_BODY(test14, tc)
+{
+ testall(-0.0, -0.0);
+}
+
+ATF_TC_WITHOUT_HEAD(test15);
+ATF_TC_BODY(test15, tc)
+{
+ testall(0.0, 0.0);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, test1);
@@ -183,6 +254,9 @@
ATF_TP_ADD_TC(tp, test10);
ATF_TP_ADD_TC(tp, test11);
ATF_TP_ADD_TC(tp, test12);
+ ATF_TP_ADD_TC(tp, test13);
+ ATF_TP_ADD_TC(tp, test14);
+ ATF_TP_ADD_TC(tp, test15);
return (atf_no_error());
}

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 17, 1:42 AM (18 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31597027
Default Alt Text
D56236.diff (34 KB)

Event Timeline