Implement truncl() based on floorl().

This commit is contained in:
David Schultz 2005-04-16 21:12:47 +00:00
parent 0f7d553f53
commit 2f2ee27de4
4 changed files with 80 additions and 12 deletions

View File

@ -55,7 +55,7 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \
s_rint.c s_rintf.c s_round.c s_roundf.c s_roundl.c \
s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \
s_signgam.c s_significand.c s_significandf.c s_sin.c s_sinf.c s_tan.c \
s_tanf.c s_tanh.c s_tanhf.c s_trunc.c s_truncf.c \
s_tanf.c s_tanh.c s_tanhf.c s_trunc.c s_truncf.c s_truncl.c \
w_cabs.c w_cabsf.c w_drem.c w_dremf.c
# Location of fpmath.h and _fpmath.h
@ -153,6 +153,6 @@ MLINKS+=sinh.3 sinhf.3
MLINKS+=sqrt.3 cbrt.3 sqrt.3 cbrtf.3 sqrt.3 sqrtf.3
MLINKS+=tan.3 tanf.3
MLINKS+=tanh.3 tanhf.3
MLINKS+=trunc.3 truncf.3
MLINKS+=trunc.3 truncf.3 truncl.3
.include <bsd.lib.mk>

View File

@ -1,4 +1,4 @@
.\" Copyright (c) 2004 David Schultz <das@FreeBSD.org>
.\" Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -24,12 +24,13 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 20, 2004
.Dd April 16, 2005
.Dt TRUNC 3
.Os
.Sh NAME
.Nm trunc ,
.Nm truncf
.Nm truncf ,
.Nm truncl
.Nd nearest integral value with magnitude less than or equal to |x|
.Sh LIBRARY
.Lb libm
@ -39,18 +40,22 @@
.Fn trunc "double x"
.Ft float
.Fn truncf "float x"
.Ft long double
.Fn truncl "long double x"
.Sh DESCRIPTION
The
.Fn trunc
.Fn trunc ,
.Fn truncf ,
and
.Fn truncf
.Fn truncl
functions return the nearest integral value with magnitude less than
or equal to
.Pf | Fa x Ns | .
They are equivalent to
.Fn rint
and
.Fn rint ,
.Fn rintf ,
and
.Fn rintl ,
respectively, in the
.Dv FE_TOWARDZERO
rounding mode.
@ -64,9 +69,10 @@ rounding mode.
.Xr round 3
.Sh STANDARDS
The
.Fn trunc
.Fn trunc ,
.Fn truncf ,
and
.Fn truncf
.Fn truncl
functions conform to
.St -isoC-99 .
.Sh HISTORY

View File

@ -464,8 +464,8 @@ long double sqrtl(long double);
long double tanhl(long double);
long double tanl(long double);
long double tgammal(long double);
long double truncl(long double);
#endif
long double truncl(long double);
#endif /* __ISO_C_VISIBLE >= 1999 */
__END_DECLS

62
lib/msun/src/s_truncl.c Normal file
View File

@ -0,0 +1,62 @@
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
* From: @(#)s_floor.c 5.1 93/09/24
*/
#ifndef lint
static char rcsid[] = "$FreeBSD$";
#endif
/*
* truncl(x)
* Return x rounded toward 0 to integral value
* Method:
* Bit twiddling.
* Exception:
* Inexact flag raised if x not equal to truncl(x).
*/
#include <float.h>
#include <math.h>
#include <stdint.h>
#include "fpmath.h"
#ifdef LDBL_IMPLICIT_NBIT
#define MANH_SIZE (LDBL_MANH_SIZE + 1)
#else
#define MANH_SIZE LDBL_MANH_SIZE
#endif
long double
truncl(long double x)
{
union IEEEl2bits u = { .e = x };
int e = u.bits.exp - LDBL_MAX_EXP + 1;
if (e < MANH_SIZE - 1) {
if (e < 0) { /* raise inexact if x != 0 */
u.e = 0.0;
} else {
uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1);
if (((u.bits.manh & m) | u.bits.manl) == 0)
return (x); /* x is integral */
u.bits.manh &= ~m;
u.bits.manl = 0;
}
} else if (e < LDBL_MANT_DIG - 1) {
uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1);
if ((u.bits.manl & m) == 0)
return (x); /* x is integral */
u.bits.manl &= ~m;
}
return (u.e);
}