lib/msun: fmaximum_mag_num family. Tests and man page
Added the fmaximum_mag_num{,f,l} and fminimum_mag_num{,f,l} functions.
PR: 294719
Reviewed by: fuz, kargl
MFC after: 1 month
This commit is contained in:
committed by
Robert Clausecker
parent
f9590540c5
commit
f62d826a6f
+13
-5
@@ -76,9 +76,11 @@ COMMON_SRCS= b_tgamma.c \
|
||||
s_finite.c s_finitef.c \
|
||||
s_floor.c s_floorf.c s_fma.c s_fmaf.c \
|
||||
s_fmax.c s_fmaxf.c s_fmaximum.c s_fmaximumf.c \
|
||||
s_fmaximum_mag.c s_fmaximum_magf.c s_fmaximum_num.c s_fmaximum_numf.c \
|
||||
s_fmaximum_mag.c s_fmaximum_magf.c s_fmaximum_mag_num.c \
|
||||
s_fmaximum_mag_numf.c s_fmaximum_num.c s_fmaximum_numf.c \
|
||||
s_fmin.c s_fminf.c s_fminimum.c s_fminimumf.c \
|
||||
s_fminimum_mag.c s_fminimum_magf.c s_fminimum_num.c s_fminimum_numf.c \
|
||||
s_fminimum_mag.c s_fminimum_magf.c s_fminimum_mag_num.c \
|
||||
s_fminimum_mag_numf.c s_fminimum_num.c s_fminimum_numf.c \
|
||||
s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \
|
||||
s_ilogbl.c s_isfinite.c s_isnan.c s_isnormal.c \
|
||||
s_llrint.c s_llrintf.c s_llround.c s_llroundf.c s_llroundl.c \
|
||||
@@ -135,8 +137,10 @@ COMMON_SRCS+= b_tgammal.c catrigl.c \
|
||||
s_asinhl.c s_atanl.c s_cbrtl.c s_ceill.c s_cexpl.c \
|
||||
s_clogl.c s_cosl.c s_cospil.c s_cprojl.c \
|
||||
s_csqrtl.c s_erfl.c s_exp2l.c s_expl.c s_floorl.c s_fmal.c \
|
||||
s_fmaxl.c s_fmaximuml.c s_fmaximum_magl.c s_fmaximum_numl.c \
|
||||
s_fminl.c s_fminimuml.c s_fminimum_magl.c s_fminimum_numl.c \
|
||||
s_fmaxl.c s_fmaximuml.c s_fmaximum_magl.c \
|
||||
s_fmaximum_numl.c s_fmaximum_mag_numl.c \
|
||||
s_fminl.c s_fminimuml.c s_fminimum_magl.c \
|
||||
s_fminimum_numl.c s_fminimum_mag_numl.c \
|
||||
s_frexpl.c s_logbl.c s_logl.c s_nanl.c \
|
||||
s_nextafterl.c s_nexttoward.c s_remquol.c s_rintl.c s_roundl.c \
|
||||
s_scalbnl.c s_sinl.c s_sincosl.c s_sinpil.c \
|
||||
@@ -182,7 +186,8 @@ MAN= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 \
|
||||
exp.3 fabs.3 fdim.3 \
|
||||
feclearexcept.3 feenableexcept.3 fegetenv.3 \
|
||||
fegetround.3 fenv.3 floor.3 fma.3 \
|
||||
fmax.3 fmaximum.3 fmaximum_mag.3 fmaximum_num.3 fmod.3 \
|
||||
fmax.3 fmaximum.3 fmaximum_mag.3 \
|
||||
fmaximum_mag_num.3 fmaximum_num.3 fmod.3 \
|
||||
hypot.3 ieee.3 ieee_test.3 ilogb.3 j0.3 \
|
||||
lgamma.3 log.3 lrint.3 lround.3 math.3 nan.3 \
|
||||
nextafter.3 remainder.3 rint.3 \
|
||||
@@ -242,6 +247,9 @@ MLINKS+=fmaximum.3 fmaximumf.3 fmaximum.3 fmaximuml.3 \
|
||||
MLINKS+=fmaximum_mag.3 fmaximum_magf.3 fmaximum_mag.3 fmaximum_magl.3 \
|
||||
fmaximum_mag.3 fminimum_mag.3 fmaximum_mag.3 fminimum_magf.3 \
|
||||
fmaximum_mag.3 fminimum_magl.3
|
||||
MLINKS+=fmaximum_mag_num.3 fmaximum_mag_numf.3 fmaximum_mag_num.3 fmaximum_mag_numl.3 \
|
||||
fmaximum_mag_num.3 fminimum_mag_num.3 fmaximum_mag_num.3 fminimum_mag_numf.3 \
|
||||
fmaximum_mag_num.3 fminimum_mag_numl.3
|
||||
MLINKS+=fmaximum_num.3 fmaximum_numf.3 fmaximum_num.3 fmaximum_numl.3 \
|
||||
fmaximum_num.3 fminimum_num.3 fmaximum_num.3 fminimum_numf.3 \
|
||||
fmaximum_num.3 fminimum_numl.3
|
||||
|
||||
+12
-6
@@ -323,19 +323,25 @@ FBSD_1.9 {
|
||||
fmaximum;
|
||||
fmaximumf;
|
||||
fmaximuml;
|
||||
fminimum;
|
||||
fminimumf;
|
||||
fminimuml;
|
||||
fmaximum_mag;
|
||||
fmaximum_magf;
|
||||
fmaximum_magl;
|
||||
fminimum_mag;
|
||||
fminimum_magf;
|
||||
fminimum_magl;
|
||||
fmaximum_mag_num;
|
||||
fmaximum_mag_numf;
|
||||
fmaximum_mag_numl;
|
||||
fmaximum_num;
|
||||
fmaximum_numf;
|
||||
fmaximum_numl;
|
||||
fminimum;
|
||||
fminimumf;
|
||||
fminimuml;
|
||||
fminimum_mag;
|
||||
fminimum_magf;
|
||||
fminimum_magl;
|
||||
fminimum_num;
|
||||
fminimum_numf;
|
||||
fminimum_numl;
|
||||
fminimum_mag_num;
|
||||
fminimum_mag_numf;
|
||||
fminimum_mag_numl;
|
||||
};
|
||||
|
||||
@@ -84,7 +84,7 @@ These routines do not raise any floating-point exceptions.
|
||||
.Sh SEE ALSO
|
||||
.Xr fmax 3 ,
|
||||
.Xr fmaximum 3 ,
|
||||
.Xr fmaximum_num 3 ,
|
||||
.Xr fmaximum_mag_num 3 ,
|
||||
.Xr math 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
.\" Copyright (c) 2004 David Schultz <das@FreeBSD.org>
|
||||
.\" Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.Dd April 3, 2026
|
||||
.Dt FMAXIMUM_MAG_NUM 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm fmaximum_mag_num ,
|
||||
.Nm fmaximum_mag_numf ,
|
||||
.Nm fmaximum_mag_numl ,
|
||||
.Nm fminimum_mag_num ,
|
||||
.Nm fminimum_mag_numf ,
|
||||
.Nm fminimum_mag_numl
|
||||
.Nd floating-point maximum and minimum magnitude number functions
|
||||
.Sh LIBRARY
|
||||
.Lb libm
|
||||
.Sh SYNOPSIS
|
||||
.In math.h
|
||||
.Ft double
|
||||
.Fn fmaximum_mag_num "double x" "double y"
|
||||
.Ft float
|
||||
.Fn fmaximum_mag_numf "float x" "float y"
|
||||
.Ft "long double"
|
||||
.Fn fmaximum_mag_numl "long double x" "long double y"
|
||||
.Ft double
|
||||
.Fn fminimum_mag_num "double x" "double y"
|
||||
.Ft float
|
||||
.Fn fminimum_mag_numf "float x" "float y"
|
||||
.Ft "long double"
|
||||
.Fn fminimum_mag_numl "long double x" "long double y"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn fmaximum_mag_num ,
|
||||
.Fn fmaximum_mag_numf ,
|
||||
and
|
||||
.Fn fmaximum_mag_numl
|
||||
functions determine the larger of the absolute values of
|
||||
.Fa x
|
||||
and
|
||||
.Fa y ,
|
||||
and return the argument with the larger absolute value,
|
||||
preferring a numeric value over an \*(Na.
|
||||
If one argument is a numeric value and the other is an \*(Na,
|
||||
the numeric value is returned.
|
||||
If the absolute values are equal, the behavior is equivalent to calling the corresponding
|
||||
.Fn fmaximum_num
|
||||
function on the arguments.
|
||||
.Pp
|
||||
Likewise, the
|
||||
.Fn fminimum_mag_num ,
|
||||
.Fn fminimum_mag_numf ,
|
||||
and
|
||||
.Fn fminimum_mag_numl
|
||||
functions determine the smaller of the absolute values of
|
||||
.Fa x
|
||||
and
|
||||
.Fa y ,
|
||||
and return the argument with the smaller absolute value,
|
||||
preferring a numeric value over an \*(Na.
|
||||
If one argument is a numeric value and the other is an \*(Na,
|
||||
the numeric value is returned.
|
||||
If the absolute values are equal, the behavior is equivalent to calling the corresponding
|
||||
.Fn fminimum_num
|
||||
function on the arguments.
|
||||
.Pp
|
||||
If both arguments are \*(Nas, a quiet \*(Na is returned.
|
||||
If either argument is a signaling \*(Na, an invalid exception is raised.
|
||||
Otherwise, these routines do not raise any floating-point exceptions.
|
||||
.Sh SEE ALSO
|
||||
.Xr fmax 3 ,
|
||||
.Xr fmaximum 3 ,
|
||||
.Xr fmaximum_mag 3 ,
|
||||
.Xr fmaximum_num 3 ,
|
||||
.Xr math 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn fmaximum_mag_num ,
|
||||
.Fn fmaximum_mag_numf ,
|
||||
.Fn fmaximum_mag_numl ,
|
||||
.Fn fminimum_mag_num ,
|
||||
.Fn fminimum_mag_numf ,
|
||||
and
|
||||
.Fn fminimum_mag_numl
|
||||
functions conform to
|
||||
.St -isoC-2023 .
|
||||
.Sh HISTORY
|
||||
These routines first appeared in
|
||||
.Fx 16.0 ..\"
|
||||
+12
-6
@@ -523,18 +523,24 @@ long double tanpil(long double);
|
||||
double fmaximum(double, double);
|
||||
float fmaximumf(float, float);
|
||||
long double fmaximuml(long double, long double);
|
||||
double fminimum(double, double);
|
||||
float fminimumf(float, float);
|
||||
long double fminimuml(long double, long double);
|
||||
double fmaximum_mag(double, double);
|
||||
float fmaximum_magf(float, float);
|
||||
long double fmaximum_magl(long double, long double);
|
||||
double fminimum_mag(double, double);
|
||||
float fminimum_magf(float, float);
|
||||
long double fminimum_magl(long double, long double);
|
||||
double fmaximum_mag_num(double, double);
|
||||
float fmaximum_mag_numf(float, float);
|
||||
long double fmaximum_mag_numl(long double, long double);
|
||||
double fmaximum_num(double, double);
|
||||
float fmaximum_numf(float, float);
|
||||
long double fmaximum_numl(long double, long double);
|
||||
double fminimum(double, double);
|
||||
float fminimumf(float, float);
|
||||
long double fminimuml(long double, long double);
|
||||
double fminimum_mag(double, double);
|
||||
float fminimum_magf(float, float);
|
||||
long double fminimum_magl(long double, long double);
|
||||
double fminimum_mag_num(double, double);
|
||||
float fminimum_mag_numf(float, float);
|
||||
long double fminimum_mag_numl(long double, long double);
|
||||
double fminimum_num(double, double);
|
||||
float fminimum_numf(float, float);
|
||||
long double fminimum_numl(long double, long double);
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
#ifdef USE_BUILTIN_FMAXIMUM_MAG_NUM
|
||||
double
|
||||
fmaximum_mag_num(double x, double y)
|
||||
{
|
||||
return (__builtin_fmaximum_mag_num(x, y));
|
||||
}
|
||||
#else
|
||||
double
|
||||
fmaximum_mag_num(double x, double y)
|
||||
{
|
||||
union IEEEd2bits u[2];
|
||||
bool nan_x, nan_y;
|
||||
|
||||
u[0].d = x;
|
||||
u[1].d = y;
|
||||
|
||||
nan_x = isnan(x);
|
||||
nan_y = isnan(y);
|
||||
|
||||
if (nan_x || nan_y) {
|
||||
/* If both are NaN, adding returns qNaN */
|
||||
if (nan_x && nan_y)
|
||||
return (x + y);
|
||||
|
||||
/* force_except makes sure sNaN's raise exceptions */
|
||||
volatile double force_except = x + y;
|
||||
force_except;
|
||||
|
||||
if (nan_x)
|
||||
return (y);
|
||||
else
|
||||
return (x);
|
||||
}
|
||||
|
||||
double ax = fabs(x);
|
||||
double ay = fabs(y);
|
||||
|
||||
if (ay > ax)
|
||||
return (y);
|
||||
if (ax > ay)
|
||||
return (x);
|
||||
|
||||
/* If magnitudes are equal, we break the tie with the sign */
|
||||
if (u[0].bits.sign != u[1].bits.sign)
|
||||
return (u[u[0].bits.sign].d);
|
||||
|
||||
return (x);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LDBL_MANT_DIG == 53)
|
||||
__weak_reference(fmaximum_mag_num, fmaximum_mag_numl);
|
||||
#endif
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
#ifdef USE_BUILTIN_FMAXIMUM_MAG_NUMF
|
||||
float
|
||||
fmaximum_mag_numf(float x, float y)
|
||||
{
|
||||
return (__builtin_fmaximum_mag_numf(x, y));
|
||||
}
|
||||
#else
|
||||
float
|
||||
fmaximum_mag_numf(float x, float y)
|
||||
{
|
||||
union IEEEf2bits u[2];
|
||||
bool nan_x, nan_y;
|
||||
|
||||
u[0].f = x;
|
||||
u[1].f = y;
|
||||
|
||||
nan_x = isnan(x);
|
||||
nan_y = isnan(y);
|
||||
|
||||
if (nan_x || nan_y) {
|
||||
/* If both are NaN, adding returns qNaN */
|
||||
if (nan_x && nan_y)
|
||||
return (x + y);
|
||||
|
||||
/* force_except makes sure sNaN's raise exceptions */
|
||||
volatile float force_except = x + y;
|
||||
force_except;
|
||||
|
||||
if (nan_x)
|
||||
return (y);
|
||||
else
|
||||
return (x);
|
||||
}
|
||||
|
||||
float ax = fabsf(x);
|
||||
float ay = fabsf(y);
|
||||
|
||||
if (ay > ax)
|
||||
return (y);
|
||||
if (ax > ay)
|
||||
return (x);
|
||||
|
||||
/* If magnitudes are equal, we break the tie with the sign */
|
||||
if (u[0].bits.sign != u[1].bits.sign)
|
||||
return (u[u[0].bits.sign].f);
|
||||
|
||||
return (x);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
long double
|
||||
fmaximum_mag_numl(long double x, long double y)
|
||||
{
|
||||
union IEEEl2bits u[2];
|
||||
bool nan_x, nan_y;
|
||||
|
||||
u[0].e = x;
|
||||
mask_nbit_l(u[0]);
|
||||
u[1].e = y;
|
||||
mask_nbit_l(u[1]);
|
||||
|
||||
nan_x = isnan(x);
|
||||
nan_y = isnan(y);
|
||||
|
||||
if (nan_x || nan_y) {
|
||||
/* If both are NaN, adding returns qNaN */
|
||||
if (nan_x && nan_y)
|
||||
return (x + y);
|
||||
|
||||
/* force_except makes sure sNaN's raise exceptions */
|
||||
volatile long double force_except = x + y;
|
||||
force_except;
|
||||
|
||||
if (nan_x)
|
||||
return (y);
|
||||
else
|
||||
return (x);
|
||||
}
|
||||
|
||||
long double ax = fabsl(x);
|
||||
long double ay = fabsl(y);
|
||||
|
||||
if (ay > ax)
|
||||
return (y);
|
||||
if (ax > ay)
|
||||
return (x);
|
||||
|
||||
/* If magnitudes are equal, we break the tie with the sign */
|
||||
if (u[0].bits.sign != u[1].bits.sign)
|
||||
return (u[0].bits.sign ? y : x);
|
||||
|
||||
return (x);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
#ifdef USE_BUILTIN_FMINIMUM_MAG_NUM
|
||||
double
|
||||
fminimum_mag_num(double x, double y)
|
||||
{
|
||||
return (__builtin_fminimum_mag_num(x, y));
|
||||
}
|
||||
#else
|
||||
double
|
||||
fminimum_mag_num(double x, double y)
|
||||
{
|
||||
union IEEEd2bits u[2];
|
||||
bool nan_x, nan_y;
|
||||
|
||||
u[0].d = x;
|
||||
u[1].d = y;
|
||||
|
||||
nan_x = isnan(x);
|
||||
nan_y = isnan(y);
|
||||
|
||||
if (nan_x || nan_y) {
|
||||
/* If both are NaN, adding returns qNaN */
|
||||
if (nan_x && nan_y)
|
||||
return (x + y);
|
||||
|
||||
/* force_except makes sure sNaN's raise exceptions */
|
||||
volatile double force_except = x + y;
|
||||
force_except;
|
||||
|
||||
if (nan_x)
|
||||
return (y);
|
||||
else
|
||||
return (x);
|
||||
}
|
||||
|
||||
double ax = fabs(x);
|
||||
double ay = fabs(y);
|
||||
|
||||
if (ay < ax)
|
||||
return (y);
|
||||
if (ax < ay)
|
||||
return (x);
|
||||
|
||||
/* If magnitudes are equal, we break the tie with the sign */
|
||||
if (u[0].bits.sign != u[1].bits.sign)
|
||||
return (u[u[1].bits.sign].d);
|
||||
|
||||
return (x);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LDBL_MANT_DIG == 53)
|
||||
__weak_reference(fminimum_mag_num, fminimum_mag_numl);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
#ifdef USE_BUILTIN_FMINIMUM_MAG_NUMF
|
||||
float
|
||||
fminimum_mag_numf(float x, float y)
|
||||
{
|
||||
return (__builtin_fminimum_mag_numf(x, y));
|
||||
}
|
||||
#else
|
||||
float
|
||||
fminimum_mag_numf(float x, float y)
|
||||
{
|
||||
union IEEEf2bits u[2];
|
||||
bool nan_x, nan_y;
|
||||
|
||||
u[0].f = x;
|
||||
u[1].f = y;
|
||||
|
||||
nan_x = isnan(x);
|
||||
nan_y = isnan(y);
|
||||
|
||||
if (nan_x || nan_y) {
|
||||
/* If both are NaN, adding returns qNaN */
|
||||
if (nan_x && nan_y)
|
||||
return (x + y);
|
||||
|
||||
/* force_except makes sure sNaN's raise exceptions */
|
||||
volatile float force_except = x + y;
|
||||
force_except;
|
||||
|
||||
if (nan_x)
|
||||
return (y);
|
||||
else
|
||||
return (x);
|
||||
}
|
||||
|
||||
float ax = fabsf(x);
|
||||
float ay = fabsf(y);
|
||||
|
||||
if (ay < ax)
|
||||
return (y);
|
||||
if (ax < ay)
|
||||
return (x);
|
||||
|
||||
/* If magnitudes are equal, we break the tie with the sign */
|
||||
if (u[0].bits.sign != u[1].bits.sign)
|
||||
return (u[u[1].bits.sign].f);
|
||||
|
||||
return (x);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2026 Jesús Blázquez <jesuscblazquez@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
long double
|
||||
fminimum_mag_numl(long double x, long double y)
|
||||
{
|
||||
union IEEEl2bits u[2];
|
||||
bool nan_x, nan_y;
|
||||
|
||||
u[0].e = x;
|
||||
mask_nbit_l(u[0]);
|
||||
u[1].e = y;
|
||||
mask_nbit_l(u[1]);
|
||||
|
||||
nan_x = isnan(x);
|
||||
nan_y = isnan(y);
|
||||
|
||||
if (nan_x || nan_y) {
|
||||
/* If both are NaN, adding returns qNaN */
|
||||
if (nan_x && nan_y)
|
||||
return (x + y);
|
||||
|
||||
/* force_except makes sure sNaN's raise exceptions */
|
||||
volatile long double force_except = x + y;
|
||||
force_except;
|
||||
|
||||
if (nan_x)
|
||||
return (y);
|
||||
else
|
||||
return (x);
|
||||
}
|
||||
|
||||
long double ax = fabsl(x);
|
||||
long double ay = fabsl(y);
|
||||
|
||||
if (ay < ax)
|
||||
return (y);
|
||||
if (ax < ay)
|
||||
return (x);
|
||||
|
||||
/* If magnitudes are equal, we break the tie with the sign */
|
||||
if (u[0].bits.sign != u[1].bits.sign)
|
||||
return (u[1].bits.sign ? y : x);
|
||||
|
||||
return (x);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
/*
|
||||
* Tests for fmaximum{,f,l}(), fminimum{,f,l}(), fmaximum_mag{,f,l},
|
||||
* fminimum_mag{,f,l}, fmaximum_num{,f,l}, fminimum_num{,f,l}
|
||||
* fminimum_mag{,f,l}, fmaximum_num{,f,l}, fminimum_num{,f,l},
|
||||
* fmaximum_mag_num{,f,l} and fminimum_mag_num{,f,l}
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
@@ -130,6 +131,30 @@ testall_num_r(long double big, long double small, int rmode) {
|
||||
TEST(fminimum_numl, long double, small, big, expected_min_num, rmode);
|
||||
}
|
||||
|
||||
static void
|
||||
testall_mag_num_r(long double big, long double small, int rmode) {
|
||||
long double expected_max_mag_num = isnan(big) ? small : big;
|
||||
long double expected_min_mag_num = isnan(small) ? big : small;
|
||||
|
||||
if (fabsl(small) > fabsl(big)) {
|
||||
expected_max_mag_num = small;
|
||||
expected_min_mag_num = big;
|
||||
}
|
||||
|
||||
TEST(fmaximum_mag_numf, float, big, small, expected_max_mag_num, rmode);
|
||||
TEST(fmaximum_mag_numf, float, small, big, expected_max_mag_num, rmode);
|
||||
TEST(fmaximum_mag_num, double, big, small, expected_max_mag_num, rmode);
|
||||
TEST(fmaximum_mag_num, double, small, big, expected_max_mag_num, rmode);
|
||||
TEST(fmaximum_mag_numl, long double, big, small, expected_max_mag_num, rmode);
|
||||
TEST(fmaximum_mag_numl, long double, small, big, expected_max_mag_num, rmode);
|
||||
TEST(fminimum_mag_numf, float, big, small, expected_min_mag_num, rmode);
|
||||
TEST(fminimum_mag_numf, float, small, big, expected_min_mag_num, rmode);
|
||||
TEST(fminimum_mag_num, double, big, small, expected_min_mag_num, rmode);
|
||||
TEST(fminimum_mag_num, double, small, big, expected_min_mag_num, rmode);
|
||||
TEST(fminimum_mag_numl, long double, big, small, expected_min_mag_num, rmode);
|
||||
TEST(fminimum_mag_numl, long double, small, big, expected_min_mag_num, rmode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test all the functions: fmaximumf, fmaximum, fmaximuml, fminimumf, fminimum, fminimuml
|
||||
* in all rounding modes and with the arguments in different orders.
|
||||
@@ -148,6 +173,7 @@ testall(long double big, long double small)
|
||||
testall_r(big, small, rmodes[i]);
|
||||
testall_mag_r(big, small, rmodes[i]);
|
||||
testall_num_r(big, small, rmodes[i]);
|
||||
testall_mag_num_r(big, small, rmodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user