xref: /csrg-svn/lib/libm/common_source/floor.c (revision 34122)
1*34122Sbostic /*
2*34122Sbostic  * Copyright (c) 1985 Regents of the University of California.
3*34122Sbostic  * All rights reserved.  The Berkeley software License Agreement
4*34122Sbostic  * specifies the terms and conditions for redistribution.
5*34122Sbostic  */
624596Szliu 
7*34122Sbostic #ifndef lint
8*34122Sbostic static char sccsid[] = "@(#)floor.c	5.2 (Berkeley) 04/29/88";
9*34122Sbostic #endif /* not lint */
10*34122Sbostic 
1124596Szliu /*
1224596Szliu  * floor and ceil-- greatest integer <= arg
1324596Szliu  * (resp least >=)
1424596Szliu  */
1524596Szliu 
1624596Szliu double	modf();
1724596Szliu 
1824596Szliu double
1924596Szliu floor(d)
2024596Szliu double d;
2124596Szliu {
2224596Szliu 	double fract;
2324596Szliu 
2424596Szliu 	if (d<0.0) {
2524596Szliu 		d = -d;
2624596Szliu 		fract = modf(d, &d);
2724596Szliu 		if (fract != 0.0)
2824596Szliu 			d += 1;
2924596Szliu 		d = -d;
3024596Szliu 	} else
3124596Szliu 		modf(d, &d);
3224596Szliu 	return(d);
3324596Szliu }
3424596Szliu 
3524596Szliu double
3624596Szliu ceil(d)
3724596Szliu double d;
3824596Szliu {
3924596Szliu 	return(-floor(-d));
4024596Szliu }
4124596Szliu 
4231853Szliu #ifndef national			/* rint() is in ./NATIONAL/support.s */
4324596Szliu /*
4424596Szliu  * algorithm for rint(x) in pseudo-pascal form ...
4524596Szliu  *
4624596Szliu  * real rint(x): real x;
4724596Szliu  *	... delivers integer nearest x in direction of prevailing rounding
4824596Szliu  *	... mode
4924596Szliu  * const	L = (last consecutive integer)/2
5024596Szliu  * 	  = 2**55; for VAX D
5124596Szliu  * 	  = 2**52; for IEEE 754 Double
5224596Szliu  * real	s,t;
5324596Szliu  * begin
5424596Szliu  * 	if x != x then return x;		... NaN
5524596Szliu  * 	if |x| >= L then return x;		... already an integer
5624596Szliu  * 	s := copysign(L,x);
5724596Szliu  * 	t := x + s;				... = (x+s) rounded to integer
5824596Szliu  * 	return t - s
5924596Szliu  * end;
6024596Szliu  *
6124596Szliu  * Note: Inexact will be signaled if x is not an integer, as is
6224596Szliu  *	customary for IEEE 754.  No other signal can be emitted.
6324596Szliu  */
6431853Szliu #if defined(vax)||defined(tahoe)
6531853Szliu #ifdef vax
6631812Szliu #define _0x(A,B)	0x/**/A/**/B
6731853Szliu #else	/* vax */
6831812Szliu #define _0x(A,B)	0x/**/B/**/A
6931853Szliu #endif	/* vax */
7031812Szliu static long Lx[] = {_0x(0000,5c00),_0x(0000,0000)};	/* 2**55 */
7124596Szliu #define L *(double *) Lx
7231853Szliu #else	/* defined(vax)||defined(tahoe) */
7324596Szliu static double L = 4503599627370496.0E0;		/* 2**52 */
7431853Szliu #endif	/* defined(vax)||defined(tahoe) */
7524596Szliu double
7624596Szliu rint(x)
7724596Szliu double x;
7824596Szliu {
7924596Szliu 	double s,t,one = 1.0,copysign();
8031853Szliu #if !defined(vax)&&!defined(tahoe)
8124596Szliu 	if (x != x)				/* NaN */
8224596Szliu 		return (x);
8331853Szliu #endif	/* !defined(vax)&&!defined(tahoe) */
8424596Szliu 	if (copysign(x,one) >= L)		/* already an integer */
8524596Szliu 	    return (x);
8624596Szliu 	s = copysign(L,x);
8724596Szliu 	t = x + s;				/* x+s rounded to integer */
8824596Szliu 	return (t - s);
8924596Szliu }
9031853Szliu #endif	/* not national */
91