xref: /csrg-svn/lib/libm/common_source/floor.c (revision 35679)
134122Sbostic /*
234122Sbostic  * Copyright (c) 1985 Regents of the University of California.
334401Sbostic  * All rights reserved.
434401Sbostic  *
534401Sbostic  * Redistribution and use in source and binary forms are permitted
634931Sbostic  * provided that the above copyright notice and this paragraph are
734931Sbostic  * duplicated in all such forms and that any documentation,
834931Sbostic  * advertising materials, and other materials related to such
934931Sbostic  * distribution and use acknowledge that the software was developed
1034931Sbostic  * by the University of California, Berkeley.  The name of the
1134931Sbostic  * University may not be used to endorse or promote products derived
1234931Sbostic  * from this software without specific prior written permission.
1334931Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434931Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534931Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1634401Sbostic  *
1734401Sbostic  * All recipients should regard themselves as participants in an ongoing
1834401Sbostic  * research project and hence should feel obligated to report their
1934401Sbostic  * experiences (good or bad) with these elementary function codes, using
2034401Sbostic  * the sendbug(8) program, to the authors.
2134122Sbostic  */
2224596Szliu 
2334122Sbostic #ifndef lint
24*35679Sbostic static char sccsid[] = "@(#)floor.c	5.5 (Berkeley) 09/22/88";
2534122Sbostic #endif /* not lint */
2634122Sbostic 
27*35679Sbostic #include "mathimpl.h"
2834401Sbostic 
29*35679Sbostic vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
30*35679Sbostic 
31*35679Sbostic ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
32*35679Sbostic 
33*35679Sbostic #ifdef vccast
34*35679Sbostic #define	L	vccast(L)
35*35679Sbostic #endif
36*35679Sbostic 
37*35679Sbostic 
38*35679Sbostic double ceil();
39*35679Sbostic double floor();
40*35679Sbostic 
4124596Szliu /*
4234401Sbostic  * floor(x) := the largest integer no larger than x;
4334401Sbostic  * ceil(x) := -floor(-x), for all real x.
4434401Sbostic  *
4534401Sbostic  * Note: Inexact will be signaled if x is not an integer, as is
4634401Sbostic  *	customary for IEEE 754.  No other signal can be emitted.
4724596Szliu  */
4824596Szliu double
4934401Sbostic floor(x)
5034401Sbostic double x;
5124596Szliu {
52*35679Sbostic 	double y;
5324596Szliu 
5434401Sbostic 	if (
5534401Sbostic #if !defined(vax)&&!defined(tahoe)
5634401Sbostic 		x != x ||	/* NaN */
5734401Sbostic #endif	/* !defined(vax)&&!defined(tahoe) */
5834401Sbostic 		x >= L)		/* already an even integer */
5934401Sbostic 		return x;
6034401Sbostic 	else if (x < (double)0)
6134401Sbostic 		return -ceil(-x);
6234401Sbostic 	else {			/* now 0 <= x < L */
6334401Sbostic 		y = L+x;		/* destructive store must be forced */
6434401Sbostic 		y -= L;			/* an integer, and |x-y| < 1 */
6534401Sbostic 		return x < y ? y-(double)1 : y;
6634401Sbostic 	}
6724596Szliu }
6824596Szliu 
6924596Szliu double
7034401Sbostic ceil(x)
7134401Sbostic double x;
7224596Szliu {
73*35679Sbostic 	double y;
7434401Sbostic 
7534401Sbostic 	if (
7634401Sbostic #if !defined(vax)&&!defined(tahoe)
7734401Sbostic 		x != x ||	/* NaN */
7834401Sbostic #endif	/* !defined(vax)&&!defined(tahoe) */
7934401Sbostic 		x >= L)		/* already an even integer */
8034401Sbostic 		return x;
8134401Sbostic 	else if (x < (double)0)
8234401Sbostic 		return -floor(-x);
8334401Sbostic 	else {			/* now 0 <= x < L */
8434401Sbostic 		y = L+x;		/* destructive store must be forced */
8534401Sbostic 		y -= L;			/* an integer, and |x-y| < 1 */
8634401Sbostic 		return x > y ? y+(double)1 : y;
8734401Sbostic 	}
8824596Szliu }
8924596Szliu 
9031853Szliu #ifndef national			/* rint() is in ./NATIONAL/support.s */
9124596Szliu /*
9224596Szliu  * algorithm for rint(x) in pseudo-pascal form ...
9324596Szliu  *
9424596Szliu  * real rint(x): real x;
9524596Szliu  *	... delivers integer nearest x in direction of prevailing rounding
9624596Szliu  *	... mode
9724596Szliu  * const	L = (last consecutive integer)/2
9824596Szliu  * 	  = 2**55; for VAX D
9924596Szliu  * 	  = 2**52; for IEEE 754 Double
10024596Szliu  * real	s,t;
10124596Szliu  * begin
10224596Szliu  * 	if x != x then return x;		... NaN
10324596Szliu  * 	if |x| >= L then return x;		... already an integer
10424596Szliu  * 	s := copysign(L,x);
10524596Szliu  * 	t := x + s;				... = (x+s) rounded to integer
10624596Szliu  * 	return t - s
10724596Szliu  * end;
10824596Szliu  *
10924596Szliu  * Note: Inexact will be signaled if x is not an integer, as is
11024596Szliu  *	customary for IEEE 754.  No other signal can be emitted.
11124596Szliu  */
11224596Szliu double
11324596Szliu rint(x)
11424596Szliu double x;
11524596Szliu {
116*35679Sbostic 	double s,t;
117*35679Sbostic 	const double one = 1.0;
118*35679Sbostic 
11931853Szliu #if !defined(vax)&&!defined(tahoe)
12024596Szliu 	if (x != x)				/* NaN */
12124596Szliu 		return (x);
12231853Szliu #endif	/* !defined(vax)&&!defined(tahoe) */
12324596Szliu 	if (copysign(x,one) >= L)		/* already an integer */
12424596Szliu 	    return (x);
12524596Szliu 	s = copysign(L,x);
12624596Szliu 	t = x + s;				/* x+s rounded to integer */
12724596Szliu 	return (t - s);
12824596Szliu }
12931853Szliu #endif	/* not national */
130