lib/msun: Added fmaximum_mag and fmaximum_num families

Added support for the f{maximum,minimum}_{mag,num} families, the new
C23 standard functions for maximum magnitude and number-preferring
maximum.  This includes modifying fmax.3, on top of D56230, to
recommend the use of fmaximum_num and fminimum_num.

Reviewed by:	fuz, kargl
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D56236
This commit is contained in:
Jesús Blázquez
2026-04-11 10:11:44 +02:00
committed by Robert Clausecker
parent de2ea5423c
commit 4e30c12973
23 changed files with 1169 additions and 11 deletions
+13 -3
View File
@@ -76,7 +76,9 @@ 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_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 @@ 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_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 @@ 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 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+=floor.3 floorf.3 floor.3 floorl.3
MLINKS+=fma.3 fmaf.3 fma.3 fmal.3
MLINKS+=fmax.3 fmaxf.3 fmax.3 fmaxl.3 \
fmax.3 fmin.3 fmax.3 fminf.3 fmax.3 fminl.3
MLINKS+=fmaximum.3 fmaximuml.3 fmaximum.3 fmaximumf.3 \
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
+12
View File
@@ -326,4 +326,16 @@ FBSD_1.9 {
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;
};
+8 -1
View File
@@ -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 @@ as being larger than
.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 .
+2 -2
View File
@@ -83,9 +83,9 @@ or
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
+102
View File
@@ -0,0 +1,102 @@
.\" 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 3
.Os
.Sh NAME
.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_mag "double x" "double y"
.Ft float
.Fn fmaximum_magf "float x" "float y"
.Ft "long double"
.Fn fmaximum_magl "long double x" "long double y"
.Ft double
.Fn fminimum_mag "double x" "double y"
.Ft float
.Fn fminimum_magf "float x" "float y"
.Ft "long double"
.Fn fminimum_magl "long double x" "long double y"
.Sh DESCRIPTION
The
.Fn fmaximum_mag ,
.Fn fmaximum_magf ,
and
.Fn fmaximum_magl
functions determine the larger of the absolute values of
.Fa x
and
.Fa y ,
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 fminimum_magl
functions determine the smaller of the absolute values of
.Fa x
and
.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
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 fmax 3 ,
.Xr fmaximum 3 ,
.Xr fmaximum_num 3 ,
.Xr math 3
.Sh STANDARDS
The
.Fn fmaximum_mag ,
.Fn fmaximum_magf ,
.Fn fmaximum_magl ,
.Fn fminimum_mag ,
.Fn fminimum_magf ,
and
.Fn fminimum_magl
functions conform to
.St -isoC-2023 .
.Sh HISTORY
These routines first appeared in
.Fx 16.0 .
+113
View File
@@ -0,0 +1,113 @@
.\" 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_NUM 3
.Os
.Sh NAME
.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_num "double x" "double y"
.Ft float
.Fn fmaximum_numf "float x" "float y"
.Ft "long double"
.Fn fmaximum_numl "long double x" "long double y"
.Ft double
.Fn fminimum_num "double x" "double y"
.Ft float
.Fn fminimum_numf "float x" "float y"
.Ft "long double"
.Fn fminimum_numl "long double x" "long double y"
.Sh DESCRIPTION
The
.Fn fmaximum_num ,
.Fn fmaximum_numf ,
and
.Fn fmaximum_numl
functions determine the larger of
.Fa x
and
.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 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 fminimum_numl
functions determine the smaller of
.Fa x
and
.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 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 fmax 3 ,
.Xr fmaximum 3 ,
.Xr fmaximum_mag 3 ,
.Xr math 3
.Sh STANDARDS
The
.Fn fmaximum_num ,
.Fn fmaximum_numf ,
.Fn fmaximum_numl ,
.Fn fminimum_num ,
.Fn fminimum_numf ,
and
.Fn fminimum_numl
functions conform to
.St -isoC-2023 .
.Sh HISTORY
These routines first appeared in
.Fx 16.0 .
+12
View File
@@ -526,6 +526,18 @@ 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_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
+73
View File
@@ -0,0 +1,73 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <float.h>
#include <math.h>
#include "fpmath.h"
#ifdef USE_BUILTIN_FMAXIMUM_MAG
double
fmaximum_mag(double x, double y)
{
return (__builtin_fmaximum_mag(x, y));
}
#else
double
fmaximum_mag(double x, double y)
{
union IEEEd2bits u[2];
u[0].d = x;
u[1].d = y;
/* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */
if ((u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0) ||
(u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0))
return (NAN);
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, fmaximum_magl);
#endif
+68
View File
@@ -0,0 +1,68 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <math.h>
#include "fpmath.h"
#ifdef USE_BUILTIN_FMAXIMUM_MAGF
float
fmaximum_magf(float x, float y)
{
return (__builtin_fmaximum_magf(x, y));
}
#else
float
fmaximum_magf(float x, float y)
{
union IEEEf2bits u[2];
u[0].f = x;
u[1].f = y;
/* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */
if ((u[0].bits.exp == 255 && u[0].bits.man != 0) ||
(u[1].bits.exp == 255 && u[1].bits.man != 0))
return (NAN);
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
+62
View File
@@ -0,0 +1,62 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <math.h>
#include "fpmath.h"
long double
fmaximum_magl(long double x, long double y)
{
union IEEEl2bits u[2];
u[0].e = x;
mask_nbit_l(u[0]);
u[1].e = y;
mask_nbit_l(u[1]);
/* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */
if ((u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0) ||
(u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0))
return (NAN);
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);
}
+74
View File
@@ -0,0 +1,74 @@
/*
* 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_NUM
double
fmaximum_num(double x, double y)
{
return (__builtin_fmaximum_num(x, y));
}
#else
double
fmaximum_num(double x, double y)
{
union IEEEd2bits u[2];
bool nan_x, nan_y;
u[0].d = x;
u[1].d = y;
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[0].bits.sign].d);
return (x > y ? x : y);
}
#endif
#if (LDBL_MANT_DIG == 53)
__weak_reference(fmaximum_num, fmaximum_numl);
#endif
+70
View File
@@ -0,0 +1,70 @@
/*
* 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_NUMF
float
fmaximum_numf(float x, float y)
{
return (__builtin_fmaximum_numf(x, y));
}
#else
float
fmaximum_numf(float x, float y)
{
union IEEEf2bits u[2];
bool nan_x, nan_y;
u[0].f = x;
u[1].f = y;
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[0].bits.sign].f);
return (x > y ? x : y);
}
#endif
+63
View File
@@ -0,0 +1,63 @@
/*
* 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_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 = 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[0].bits.sign ? y : x);
return (x > y ? x : y);
}
+1 -1
View File
@@ -47,7 +47,7 @@ fminimum(double x, double y)
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);
+74
View File
@@ -0,0 +1,74 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <float.h>
#include <math.h>
#include "fpmath.h"
#ifdef USE_BUILTIN_FMINIMUM_MAG
double
fminimum_mag(double x, double y)
{
return (__builtin_fminimum_mag(x, y));
}
#else
double
fminimum_mag(double x, double y)
{
union IEEEd2bits u[2];
u[0].d = x;
u[1].d = y;
/* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */
if (u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0 ||
u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0)
return (NAN);
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, fminimum_magl);
#endif
+69
View File
@@ -0,0 +1,69 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <math.h>
#include "fpmath.h"
#ifdef USE_BUILTIN_FMINIMUM_MAGF
float
fminimum_magf(float x, float y)
{
return (__builtin_fminimum_magf(x, y));
}
#else
float
fminimum_magf(float x, float y)
{
union IEEEf2bits u[2];
u[0].f = x;
u[1].f = y;
/* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */
if (u[0].bits.exp == 255 && u[0].bits.man != 0 ||
u[1].bits.exp == 255 && u[1].bits.man != 0)
return (NAN);
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
+63
View File
@@ -0,0 +1,63 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <math.h>
#include "fpmath.h"
long double
fminimum_magl(long double x, long double y)
{
union IEEEl2bits u[2];
u[0].e = x;
mask_nbit_l(u[0]);
u[1].e = y;
mask_nbit_l(u[1]);
/* Handle NaN according to ISO/IEC 60559. NaN argument -> NaN return */
if (u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0 ||
u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0)
return (NAN);
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);
}
+76
View File
@@ -0,0 +1,76 @@
/*
* 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_NUM
double
fminimum_num(double x, double y)
{
return (__builtin_fminimum_num(x, y));
}
#else
double
fminimum_num(double x, double y)
{
union IEEEd2bits u[2];
bool nan_x, nan_y;
u[0].d = x;
u[1].d = y;
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 (x < y ? x : y);
}
#endif
#if (LDBL_MANT_DIG == 53)
__weak_reference(fminimum_num, fminimum_numl);
#endif
+71
View File
@@ -0,0 +1,71 @@
/*
* 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_NUMF
float
fminimum_numf(float x, float y)
{
return (__builtin_fminimum_numf(x, y));
}
#else
float
fminimum_numf(float x, float y)
{
union IEEEf2bits u[2];
bool nan_x, nan_y;
u[0].f = x;
u[1].f = y;
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 (x < y ? x : y);
}
#endif
+65
View File
@@ -0,0 +1,65 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <math.h>
#include <stdbool.h>
#include "fpmath.h"
long double
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]);
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 (x < y ? x : y);
}
+1 -1
View File
@@ -46,7 +46,7 @@ fminimumf(float x, float y)
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);
+1 -1
View File
@@ -41,7 +41,7 @@ fminimuml(long double x, long double y)
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);
+76 -2
View File
@@ -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 @@ testall_r(long double big, long double small, int rmode)
{
long double expected_max, expected_min;
if (isnan(big) || isnan(small)) {
expected_max = big + small;
expected_max = NAN;
expected_min = expected_max;
} else {
expected_max = big;
@@ -79,6 +81,55 @@ testall_r(long double big, long double small, int rmode)
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 @@ testall(long double big, long double small)
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_BODY(test12, tc)
}
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_TCS(tp)
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());
}