Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Jan 2004 15:34:09 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Steve Kargl <sgk@troutmask.apl.washington.edu>
Cc:        freebsd-standards@FreeBSD.ORG
Subject:   Re: Implementing C99's roundf(), round(), and roundl()
Message-ID:  <20040120145749.I2417@gamplex.bde.org>
In-Reply-To: <20040119221314.GA65652@troutmask.apl.washington.edu>
References:  <20031129000133.GA30662@troutmask.apl.washington.edu> <20031129163105.GA32651@troutmask.apl.washington.edu> <20031201182219.O4431@gamplex.bde.org> <20031202091936.I8778@gamplex.bde.org> <20040119221314.GA65652@troutmask.apl.washington.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 19 Jan 2004, Steve Kargl wrote:

> On Mon, Jan 19, 2004 at 01:31:42PM -0800, David Schultz wrote:
> >
> > 	double
> > 	round(double x)
> > 	{
> > 		double result;
> > 		fp_except_t fe;
> >
> > 		fe = fpresetsticky(0);
> > 		result = rint(x);
> > 		if (fpgetsticky() & FP_X_IMP) {
> > 			result = copysign(floor(fabs(x) + 0.5), x);
> > 			fe |= FP_X_IMP;
> > 		}
> > 		fpresetsticky(fe);
> > 		return (result);
> > 	}
> >
> > Does this seem reasonable?
>
> Don't you need
>
>         rnd = fpsetround(FP_RN); /* Set to known rounding mode */
> 		result = rint(x);
>         fpsetround(rnd);         /* Reset to whatever the user had */
>
> to ensure that rint() rounds to an expected value.

rint() may (and apparently does in at least our i386 implementation)
raise the inexact exception when it does any rounding.  So if rounding
is needed then it is needed only in the inexact exception case, and
David's point is to avoid it there.

> int main(void) {
>     double u, v, x;
>     x = 0.5;
>     fpsetround(FP_RM);
>     u = round(x);
>     fpsetround(FP_RP);
>     v = round(x);
>     /* Does u equal v ? */
> }

Testing on i386's shows that it does :-).

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040120145749.I2417>