xref: /csrg-svn/lib/libm/common_source/floor.c (revision 34931)
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
6*34931Sbostic  * provided that the above copyright notice and this paragraph are
7*34931Sbostic  * duplicated in all such forms and that any documentation,
8*34931Sbostic  * advertising materials, and other materials related to such
9*34931Sbostic  * distribution and use acknowledge that the software was developed
10*34931Sbostic  * by the University of California, Berkeley.  The name of the
11*34931Sbostic  * University may not be used to endorse or promote products derived
12*34931Sbostic  * from this software without specific prior written permission.
13*34931Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34931Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34931Sbostic  * 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*34931Sbostic static char sccsid[] = "@(#)floor.c	5.4 (Berkeley) 06/30/88";
2534122Sbostic #endif /* not lint */
2634122Sbostic 
2734401Sbostic #if defined(vax)||defined(tahoe)
2834401Sbostic #ifdef vax
2934401Sbostic #define _0x(A,B)	0x/**/A/**/B
3034401Sbostic #else	/* vax */
3134401Sbostic #define _0x(A,B)	0x/**/B/**/A
3234401Sbostic #endif	/* vax */
3334401Sbostic static long Lx[] = {_0x(0000,5c00),_0x(0000,0000)};	/* 2**55 */
3434401Sbostic #define L *(double *) Lx
3534401Sbostic #else	/* defined(vax)||defined(tahoe) */
3634401Sbostic static double L = 4503599627370496.0E0;		/* 2**52 */
3734401Sbostic #endif	/* defined(vax)||defined(tahoe) */
3834401Sbostic 
3924596Szliu /*
4034401Sbostic  * floor(x) := the largest integer no larger than x;
4134401Sbostic  * ceil(x) := -floor(-x), for all real x.
4234401Sbostic  *
4334401Sbostic  * Note: Inexact will be signaled if x is not an integer, as is
4434401Sbostic  *	customary for IEEE 754.  No other signal can be emitted.
4524596Szliu  */
4624596Szliu double
4734401Sbostic floor(x)
4834401Sbostic double x;
4924596Szliu {
5034401Sbostic 	double y,ceil();
5124596Szliu 
5234401Sbostic 	if (
5334401Sbostic #if !defined(vax)&&!defined(tahoe)
5434401Sbostic 		x != x ||	/* NaN */
5534401Sbostic #endif	/* !defined(vax)&&!defined(tahoe) */
5634401Sbostic 		x >= L)		/* already an even integer */
5734401Sbostic 		return x;
5834401Sbostic 	else if (x < (double)0)
5934401Sbostic 		return -ceil(-x);
6034401Sbostic 	else {			/* now 0 <= x < L */
6134401Sbostic 		y = L+x;		/* destructive store must be forced */
6234401Sbostic 		y -= L;			/* an integer, and |x-y| < 1 */
6334401Sbostic 		return x < y ? y-(double)1 : y;
6434401Sbostic 	}
6524596Szliu }
6624596Szliu 
6724596Szliu double
6834401Sbostic ceil(x)
6934401Sbostic double x;
7024596Szliu {
7134401Sbostic 	double y,floor();
7234401Sbostic 
7334401Sbostic 	if (
7434401Sbostic #if !defined(vax)&&!defined(tahoe)
7534401Sbostic 		x != x ||	/* NaN */
7634401Sbostic #endif	/* !defined(vax)&&!defined(tahoe) */
7734401Sbostic 		x >= L)		/* already an even integer */
7834401Sbostic 		return x;
7934401Sbostic 	else if (x < (double)0)
8034401Sbostic 		return -floor(-x);
8134401Sbostic 	else {			/* now 0 <= x < L */
8234401Sbostic 		y = L+x;		/* destructive store must be forced */
8334401Sbostic 		y -= L;			/* an integer, and |x-y| < 1 */
8434401Sbostic 		return x > y ? y+(double)1 : y;
8534401Sbostic 	}
8624596Szliu }
8724596Szliu 
8831853Szliu #ifndef national			/* rint() is in ./NATIONAL/support.s */
8924596Szliu /*
9024596Szliu  * algorithm for rint(x) in pseudo-pascal form ...
9124596Szliu  *
9224596Szliu  * real rint(x): real x;
9324596Szliu  *	... delivers integer nearest x in direction of prevailing rounding
9424596Szliu  *	... mode
9524596Szliu  * const	L = (last consecutive integer)/2
9624596Szliu  * 	  = 2**55; for VAX D
9724596Szliu  * 	  = 2**52; for IEEE 754 Double
9824596Szliu  * real	s,t;
9924596Szliu  * begin
10024596Szliu  * 	if x != x then return x;		... NaN
10124596Szliu  * 	if |x| >= L then return x;		... already an integer
10224596Szliu  * 	s := copysign(L,x);
10324596Szliu  * 	t := x + s;				... = (x+s) rounded to integer
10424596Szliu  * 	return t - s
10524596Szliu  * end;
10624596Szliu  *
10724596Szliu  * Note: Inexact will be signaled if x is not an integer, as is
10824596Szliu  *	customary for IEEE 754.  No other signal can be emitted.
10924596Szliu  */
11024596Szliu double
11124596Szliu rint(x)
11224596Szliu double x;
11324596Szliu {
11424596Szliu 	double s,t,one = 1.0,copysign();
11531853Szliu #if !defined(vax)&&!defined(tahoe)
11624596Szliu 	if (x != x)				/* NaN */
11724596Szliu 		return (x);
11831853Szliu #endif	/* !defined(vax)&&!defined(tahoe) */
11924596Szliu 	if (copysign(x,one) >= L)		/* already an integer */
12024596Szliu 	    return (x);
12124596Szliu 	s = copysign(L,x);
12224596Szliu 	t = x + s;				/* x+s rounded to integer */
12324596Szliu 	return (t - s);
12424596Szliu }
12531853Szliu #endif	/* not national */
126