Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152621031
D56236.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
34 KB
Referenced Files
None
Subscribers
None
D56236.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D56236: lib/msun: Added fmaximum_mag and fmaximum_num families. Tests and man
Attached
Detach File
Event Timeline
Log In to Comment