Implement rintl(), nearbyintl(), lrintl(), and llrintl().

Thanks to bde@ for feedback and testing of rintl().
This commit is contained in:
David Schultz 2008-01-14 02:12:07 +00:00
parent 20532d115c
commit d3f9671a7d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=175309
18 changed files with 383 additions and 35 deletions

View file

@ -75,11 +75,11 @@ VERSION_DEF= ${LIBCDIR}/Versions.def
SYMBOL_MAPS= ${SYM_MAPS}
# C99 long double functions
COMMON_SRCS+= s_copysignl.c s_fabsl.c s_modfl.c
COMMON_SRCS+= s_copysignl.c s_fabsl.c s_llrintl.c s_lrintl.c s_modfl.c
.if ${LDBL_PREC} != 53
# If long double != double use these; otherwise, we alias the double versions.
COMMON_SRCS+= s_fmal.c s_frexpl.c s_logbl.c s_nanl.c \
s_nextafterl.c s_nexttoward.c s_scalbnl.c
s_nextafterl.c s_nexttoward.c s_rintl.c s_scalbnl.c
.endif
# C99 complex functions
@ -150,7 +150,8 @@ MLINKS+=ilogb.3 ilogbf.3 ilogb.3 ilogbl.3 \
MLINKS+=j0.3 j1.3 j0.3 jn.3 j0.3 y0.3 j0.3 y1.3 j0.3 y1f.3 j0.3 yn.3
MLINKS+=j0.3 j0f.3 j0.3 j1f.3 j0.3 jnf.3 j0.3 y0f.3 j0.3 ynf.3
MLINKS+=lgamma.3 gamma.3 lgamma.3 gammaf.3 lgamma.3 lgammaf.3 lgamma.3 tgamma.3
MLINKS+=lrint.3 llrint.3 lrint.3 llrintf.3 lrint.3 lrintf.3
MLINKS+=lrint.3 llrint.3 lrint.3 llrintf.3 lrint.3 llrintl.3 \
lrint.3 lrintf.3 lrint.3 lrintl.3
MLINKS+=lround.3 llround.3 lround.3 llroundf.3 lround.3 llroundl.3 \
lround.3 lroundf.3 lround.3 lroundl.3
MLINKS+=nan.3 nanf.3 nan.3 nanl.3
@ -159,7 +160,8 @@ MLINKS+=nextafter.3 nexttoward.3 nextafter.3 nexttowardf.3
MLINKS+=nextafter.3 nexttowardl.3
MLINKS+=remainder.3 remainderf.3
MLINKS+=remainder.3 remquo.3 remainder.3 remquof.3
MLINKS+=rint.3 rintf.3 rint.3 nearbyint.3 rint.3 nearbyintf.3
MLINKS+=rint.3 rintf.3 rint.3 rintl.3 \
rint.3 nearbyint.3 rint.3 nearbyintf.3 rint.3 nearbyintl.3
MLINKS+=round.3 roundf.3 round.3 roundl.3
MLINKS+=scalbn.3 scalbln.3 scalbn.3 scalblnf.3 scalbn.3 scalblnl.3
MLINKS+=scalbn.3 scalbnf.3 scalbn.3 scalbnl.3

View file

@ -193,4 +193,8 @@ FBSD_1.1 {
nan;
nanf;
nanl;
llrintl;
lrintl;
nearbyintl;
rintl;
};

View file

@ -1,7 +1,7 @@
# $FreeBSD$
ARCH_SRCS = e_sqrt.S e_sqrtf.S s_llrint.S s_llrintf.S \
s_logbl.S s_lrint.S s_lrintf.S \
s_remquo.S s_remquof.S s_scalbn.S s_scalbnf.S s_scalbnl.S
ARCH_SRCS = e_sqrt.S e_sqrtf.S s_llrint.S s_llrintf.S s_llrintl.S \
s_logbl.S s_lrint.S s_lrintf.S s_lrintl.S \
s_remquo.S s_remquof.S s_rintl.S s_scalbn.S s_scalbnf.S s_scalbnl.S
LDBL_PREC = 64
SYM_MAPS += ${.CURDIR}/amd64/Symbol.map

View file

@ -0,0 +1,35 @@
/*-
* Copyright (c) 2005 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 <machine/asm.h>
__FBSDID("$FreeBSD$");
ENTRY(llrintl)
fldt 8(%rsp)
subq $8,%rsp
fistpll (%rsp)
popq %rax
ret

35
lib/msun/amd64/s_lrintl.S Normal file
View file

@ -0,0 +1,35 @@
/*-
* Copyright (c) 2008 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 <machine/asm.h>
__FBSDID("$FreeBSD$");
ENTRY(lrintl)
fldt 8(%rsp)
subq $8,%rsp
fistpll (%rsp)
popq %rax
ret

43
lib/msun/amd64/s_rintl.S Normal file
View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 1993,94 Winning Strategies, Inc.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Winning Strategies, Inc.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
*
* $FreeBSD$
*/
/*
* Written by:
* J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
*/
#include <machine/asm.h>
ENTRY(rintl)
fldt 8(%rsp)
frndint
ret

View file

@ -13,7 +13,8 @@ ARCH_SRCS+= e_log10f.S e_logf.S e_remainderf.S \
s_remquof.S s_rintf.S s_scalbnf.S s_significandf.S s_truncf.S
# long double counterparts
ARCH_SRCS+= s_ceill.S s_copysignl.S s_floorl.S s_logbl.S s_scalbnl.S s_truncl.S
ARCH_SRCS+= s_ceill.S s_copysignl.S s_floorl.S s_llrintl.S \
s_logbl.S s_lrintl.S s_rintl.S s_scalbnl.S s_truncl.S
LDBL_PREC = 64 # XXX 64-bit format, but truncated to 53 bits
SYM_MAPS += ${.CURDIR}/i387/Symbol.map

36
lib/msun/i387/s_llrintl.S Normal file
View file

@ -0,0 +1,36 @@
/*-
* Copyright (c) 2005 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 <machine/asm.h>
__FBSDID("$FreeBSD$");
ENTRY(llrintl)
fldt 4(%esp)
subl $8,%esp
fistpll (%esp)
popl %eax
popl %edx
ret

35
lib/msun/i387/s_lrintl.S Normal file
View file

@ -0,0 +1,35 @@
/*-
* Copyright (c) 2008 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 <machine/asm.h>
__FBSDID("$FreeBSD$");
ENTRY(lrintl)
fldt 4(%esp)
subl $4,%esp
fistpl (%esp)
popl %eax
ret

43
lib/msun/i387/s_rintl.S Normal file
View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 1993,94 Winning Strategies, Inc.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Winning Strategies, Inc.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
*/
/*
* Written by:
* J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
*/
#include <machine/asm.h>
RCSID("$FreeBSD$")
ENTRY(rintl)
fldt 4(%esp)
frndint
ret

View file

@ -24,14 +24,16 @@
.\"
.\" $FreeBSD$
.\"
.Dd January 11, 2005
.Dd January 13, 2008
.Dt LRINT 3
.Os
.Sh NAME
.Nm llrint ,
.Nm llrintf ,
.Nm llrintl ,
.Nm lrint ,
.Nm lrintf
.Nm lrintf ,
.Nm lrintl
.Nd "convert to integer"
.Sh LIBRARY
.Lb libm
@ -41,10 +43,14 @@
.Fn llrint "double x"
.Ft "long long"
.Fn llrintf "float x"
.Ft "long long"
.Fn llrintl "long double x"
.Ft long
.Fn lrint "double x"
.Ft long
.Fn lrintf "float x"
.Ft long
.Fn lrintl "long double x"
.Sh DESCRIPTION
The
.Fn lrint
@ -70,8 +76,10 @@ is equivalent to
The
.Fn llrint ,
.Fn llrintf ,
.Fn llrintl ,
.Fn lrintf ,
and
.Fn lrintf
.Fn lrintl
functions differ from
.Fn lrint
only in their input and output types.
@ -81,14 +89,16 @@ only in their input and output types.
.Xr rint 3 ,
.Xr round 3
.Sh STANDARDS
These functions conform to
.St -isoC-99 .
.Sh HISTORY
The
.Fn llrint ,
.Fn llrintf ,
.Fn lrint ,
and
.Fn lrintf
functions conform to
.St -isoC-99 .
.Sh HISTORY
These routines first appeared in
routines first appeared in
.Fx 5.4 .
The long double variants were introduced in
.Fx 8.0 .

View file

@ -28,14 +28,16 @@
.\" from: @(#)rint.3 5.1 (Berkeley) 5/2/91
.\" $FreeBSD$
.\"
.Dd July 5, 2004
.Dd January 13, 2008
.Dt RINT 3
.Os
.Sh NAME
.Nm nearbyint ,
.Nm nearbyintf ,
.Nm nearbyintl ,
.Nm rint ,
.Nm rintf
.Nm rintf ,
.Nm rintl
.Nd round to integral value in floating-point format
.Sh LIBRARY
.Lb libm
@ -45,15 +47,20 @@
.Fn nearbyint "double x"
.Ft float
.Fn nearbyintf "float x"
.Ft long double
.Fn nearbyintl "long double x"
.Ft double
.Fn rint "double x"
.Ft float
.Fn rintf "float x"
.Ft long double
.Fn rintl "long double x"
.Sh DESCRIPTION
The
.Fn rint
and the
.Fn rintf
.Fn rint ,
.Fn rintf ,
and
.Fn rintl
functions return the integral value nearest to
.Fa x
according to the prevailing rounding mode.
@ -61,9 +68,10 @@ These functions raise an inexact exception when the original argument
is not an exact integer.
.Pp
The
.Fn nearbyint
.Fn nearbyint ,
.Fn nearbyintf ,
and
.Fn nearbyintf
.Fn nearbyintl
functions perform the same operation, except that they do not raise
an inexact exception.
.Sh SEE ALSO
@ -78,13 +86,7 @@ an inexact exception.
.Xr math 3 ,
.Xr round 3
.Sh STANDARDS
The
.Fn nearbyint ,
.Fn nearbyintf ,
.Fn rint ,
and
.Fn rintf
functions conform to
These functions conform to
.St -isoC-99 .
.Sh HISTORY
A
@ -96,4 +98,6 @@ The
and
.Fn nearbyintf
functions appeared in
.Fx 5.3 .
.Fx 5.3 ,
and the long double variants were first available in
.Fx 8.0 .

View file

@ -429,8 +429,8 @@ int ilogbl(long double) __pure2;
long double ldexpl(long double, int);
#if 0
long double lgammal(long double);
long long llrintl(long double);
#endif
long long llrintl(long double);
long long llroundl(long double);
#if 0
long double log10l(long double);
@ -440,14 +440,12 @@ long double log2l(long double);
long double logbl(long double);
#if 0
long double logl(long double);
long lrintl(long double);
#endif
long lrintl(long double);
long lroundl(long double);
long double modfl(long double, long double *); /* fundamentally !__pure2 */
long double nanl(const char *) __pure2;
#if 0
long double nearbyintl(long double);
#endif
long double nextafterl(long double, long double);
double nexttoward(double, long double);
float nexttowardf(float, long double);
@ -456,8 +454,8 @@ long double nexttowardl(long double, long double);
long double powl(long double, long double);
long double remainderl(long double, long double);
long double remquol(long double, long double, int *);
long double rintl(long double);
#endif
long double rintl(long double);
long double roundl(long double);
long double scalblnl(long double, long);
long double scalbnl(long double, int);

9
lib/msun/src/s_llrintl.c Normal file
View file

@ -0,0 +1,9 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define type long double
#define roundit rintl
#define dtype long long
#define fn llrintl
#include "s_lrint.c"

9
lib/msun/src/s_lrintl.c Normal file
View file

@ -0,0 +1,9 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define type long double
#define roundit rintl
#define dtype long
#define fn lrintl
#include "s_lrint.c"

View file

@ -52,3 +52,4 @@ fn(type x) \
DECL(double, nearbyint, rint)
DECL(float, nearbyintf, rintf)
DECL(long double, nearbyintl, rintl)

View file

@ -24,6 +24,8 @@ static char rcsid[] = "$FreeBSD$";
* Inexact flag raised if x not equal to rint(x).
*/
#include <float.h>
#include "math.h"
#include "math_private.h"
@ -85,3 +87,7 @@ rint(double x)
*(volatile double *)&w = TWO52[sx]+x; /* clip any extra precision */
return w-TWO52[sx];
}
#if (LDBL_MANT_DIG == 53)
__weak_reference(rint, rintl);
#endif

77
lib/msun/src/s_rintl.c Normal file
View file

@ -0,0 +1,77 @@
/*-
* Copyright (c) 2008 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <float.h>
#include <math.h>
#include "fpmath.h"
static const long double
shift[2]={
#if LDBL_MANT_DIG == 64
0x1.0p63, -0x1.0p63
#elif LDBL_MANT_DIG == 113
0x1.0p112, -0x1.0p112
#else
#error "Unsupported long double format"
#endif
};
long double
rintl(long double x)
{
union IEEEl2bits u;
short sign;
u.e = x;
if (u.bits.exp >= LDBL_MANT_DIG + LDBL_MAX_EXP - 2) {
/*
* The biased exponent is greater than the number of digits
* in the mantissa, so x is inf, NaN, or an integer.
*/
if (u.bits.exp == 2 * LDBL_MAX_EXP - 1)
return (x + x); /* inf or NaN */
else
return (x);
}
/*
* The following code assumes that intermediate results are
* evaluated in long double precision. If they are evaluated in
* greater precision, double rounding will occur, and if they are
* evaluated in less precision (as on i386), results will be
* wildly incorrect.
*/
sign = u.bits.sign;
u.e = shift[sign] + x;
u.e -= shift[sign];
u.bits.sign = sign;
return (u.e);
}