xref: /csrg-svn/lib/libm/common_source/floor.c (revision 42657)
134122Sbostic /*
234122Sbostic  * Copyright (c) 1985 Regents of the University of California.
334401Sbostic  * All rights reserved.
434401Sbostic  *
5*42657Sbostic  * %sccs.include.redist.c%
634401Sbostic  *
734401Sbostic  * All recipients should regard themselves as participants in an ongoing
834401Sbostic  * research project and hence should feel obligated to report their
934401Sbostic  * experiences (good or bad) with these elementary function codes, using
1034401Sbostic  * the sendbug(8) program, to the authors.
1134122Sbostic  */
1224596Szliu 
1334122Sbostic #ifndef lint
14*42657Sbostic static char sccsid[] = "@(#)floor.c	5.6 (Berkeley) 06/01/90";
1534122Sbostic #endif /* not lint */
1634122Sbostic 
1735679Sbostic #include "mathimpl.h"
1834401Sbostic 
1935679Sbostic vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
2035679Sbostic 
2135679Sbostic ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
2235679Sbostic 
2335679Sbostic #ifdef vccast
2435679Sbostic #define	L	vccast(L)
2535679Sbostic #endif
2635679Sbostic 
2735679Sbostic 
2835679Sbostic double ceil();
2935679Sbostic double floor();
3035679Sbostic 
3124596Szliu /*
3234401Sbostic  * floor(x) := the largest integer no larger than x;
3334401Sbostic  * ceil(x) := -floor(-x), for all real x.
3434401Sbostic  *
3534401Sbostic  * Note: Inexact will be signaled if x is not an integer, as is
3634401Sbostic  *	customary for IEEE 754.  No other signal can be emitted.
3724596Szliu  */
3824596Szliu double
3934401Sbostic floor(x)
4034401Sbostic double x;
4124596Szliu {
4235679Sbostic 	double y;
4324596Szliu 
4434401Sbostic 	if (
4534401Sbostic #if !defined(vax)&&!defined(tahoe)
4634401Sbostic 		x != x ||	/* NaN */
4734401Sbostic #endif	/* !defined(vax)&&!defined(tahoe) */
4834401Sbostic 		x >= L)		/* already an even integer */
4934401Sbostic 		return x;
5034401Sbostic 	else if (x < (double)0)
5134401Sbostic 		return -ceil(-x);
5234401Sbostic 	else {			/* now 0 <= x < L */
5334401Sbostic 		y = L+x;		/* destructive store must be forced */
5434401Sbostic 		y -= L;			/* an integer, and |x-y| < 1 */
5534401Sbostic 		return x < y ? y-(double)1 : y;
5634401Sbostic 	}
5724596Szliu }
5824596Szliu 
5924596Szliu double
6034401Sbostic ceil(x)
6134401Sbostic double x;
6224596Szliu {
6335679Sbostic 	double y;
6434401Sbostic 
6534401Sbostic 	if (
6634401Sbostic #if !defined(vax)&&!defined(tahoe)
6734401Sbostic 		x != x ||	/* NaN */
6834401Sbostic #endif	/* !defined(vax)&&!defined(tahoe) */
6934401Sbostic 		x >= L)		/* already an even integer */
7034401Sbostic 		return x;
7134401Sbostic 	else if (x < (double)0)
7234401Sbostic 		return -floor(-x);
7334401Sbostic 	else {			/* now 0 <= x < L */
7434401Sbostic 		y = L+x;		/* destructive store must be forced */
7534401Sbostic 		y -= L;			/* an integer, and |x-y| < 1 */
7634401Sbostic 		return x > y ? y+(double)1 : y;
7734401Sbostic 	}
7824596Szliu }
7924596Szliu 
8031853Szliu #ifndef national			/* rint() is in ./NATIONAL/support.s */
8124596Szliu /*
8224596Szliu  * algorithm for rint(x) in pseudo-pascal form ...
8324596Szliu  *
8424596Szliu  * real rint(x): real x;
8524596Szliu  *	... delivers integer nearest x in direction of prevailing rounding
8624596Szliu  *	... mode
8724596Szliu  * const	L = (last consecutive integer)/2
8824596Szliu  * 	  = 2**55; for VAX D
8924596Szliu  * 	  = 2**52; for IEEE 754 Double
9024596Szliu  * real	s,t;
9124596Szliu  * begin
9224596Szliu  * 	if x != x then return x;		... NaN
9324596Szliu  * 	if |x| >= L then return x;		... already an integer
9424596Szliu  * 	s := copysign(L,x);
9524596Szliu  * 	t := x + s;				... = (x+s) rounded to integer
9624596Szliu  * 	return t - s
9724596Szliu  * end;
9824596Szliu  *
9924596Szliu  * Note: Inexact will be signaled if x is not an integer, as is
10024596Szliu  *	customary for IEEE 754.  No other signal can be emitted.
10124596Szliu  */
10224596Szliu double
10324596Szliu rint(x)
10424596Szliu double x;
10524596Szliu {
10635679Sbostic 	double s,t;
10735679Sbostic 	const double one = 1.0;
10835679Sbostic 
10931853Szliu #if !defined(vax)&&!defined(tahoe)
11024596Szliu 	if (x != x)				/* NaN */
11124596Szliu 		return (x);
11231853Szliu #endif	/* !defined(vax)&&!defined(tahoe) */
11324596Szliu 	if (copysign(x,one) >= L)		/* already an integer */
11424596Szliu 	    return (x);
11524596Szliu 	s = copysign(L,x);
11624596Szliu 	t = x + s;				/* x+s rounded to integer */
11724596Szliu 	return (t - s);
11824596Szliu }
11931853Szliu #endif	/* not national */
120