xref: /csrg-svn/lib/libm/common_source/floor.c (revision 34401)
1 /*
2  * Copyright (c) 1985 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of California at Berkeley. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  *
12  * All recipients should regard themselves as participants in an ongoing
13  * research project and hence should feel obligated to report their
14  * experiences (good or bad) with these elementary function codes, using
15  * the sendbug(8) program, to the authors.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)floor.c	5.3 (Berkeley) 05/21/88";
20 #endif /* not lint */
21 
22 #if defined(vax)||defined(tahoe)
23 #ifdef vax
24 #define _0x(A,B)	0x/**/A/**/B
25 #else	/* vax */
26 #define _0x(A,B)	0x/**/B/**/A
27 #endif	/* vax */
28 static long Lx[] = {_0x(0000,5c00),_0x(0000,0000)};	/* 2**55 */
29 #define L *(double *) Lx
30 #else	/* defined(vax)||defined(tahoe) */
31 static double L = 4503599627370496.0E0;		/* 2**52 */
32 #endif	/* defined(vax)||defined(tahoe) */
33 
34 /*
35  * floor(x) := the largest integer no larger than x;
36  * ceil(x) := -floor(-x), for all real x.
37  *
38  * Note: Inexact will be signaled if x is not an integer, as is
39  *	customary for IEEE 754.  No other signal can be emitted.
40  */
41 double
42 floor(x)
43 double x;
44 {
45 	double y,ceil();
46 
47 	if (
48 #if !defined(vax)&&!defined(tahoe)
49 		x != x ||	/* NaN */
50 #endif	/* !defined(vax)&&!defined(tahoe) */
51 		x >= L)		/* already an even integer */
52 		return x;
53 	else if (x < (double)0)
54 		return -ceil(-x);
55 	else {			/* now 0 <= x < L */
56 		y = L+x;		/* destructive store must be forced */
57 		y -= L;			/* an integer, and |x-y| < 1 */
58 		return x < y ? y-(double)1 : y;
59 	}
60 }
61 
62 double
63 ceil(x)
64 double x;
65 {
66 	double y,floor();
67 
68 	if (
69 #if !defined(vax)&&!defined(tahoe)
70 		x != x ||	/* NaN */
71 #endif	/* !defined(vax)&&!defined(tahoe) */
72 		x >= L)		/* already an even integer */
73 		return x;
74 	else if (x < (double)0)
75 		return -floor(-x);
76 	else {			/* now 0 <= x < L */
77 		y = L+x;		/* destructive store must be forced */
78 		y -= L;			/* an integer, and |x-y| < 1 */
79 		return x > y ? y+(double)1 : y;
80 	}
81 }
82 
83 #ifndef national			/* rint() is in ./NATIONAL/support.s */
84 /*
85  * algorithm for rint(x) in pseudo-pascal form ...
86  *
87  * real rint(x): real x;
88  *	... delivers integer nearest x in direction of prevailing rounding
89  *	... mode
90  * const	L = (last consecutive integer)/2
91  * 	  = 2**55; for VAX D
92  * 	  = 2**52; for IEEE 754 Double
93  * real	s,t;
94  * begin
95  * 	if x != x then return x;		... NaN
96  * 	if |x| >= L then return x;		... already an integer
97  * 	s := copysign(L,x);
98  * 	t := x + s;				... = (x+s) rounded to integer
99  * 	return t - s
100  * end;
101  *
102  * Note: Inexact will be signaled if x is not an integer, as is
103  *	customary for IEEE 754.  No other signal can be emitted.
104  */
105 double
106 rint(x)
107 double x;
108 {
109 	double s,t,one = 1.0,copysign();
110 #if !defined(vax)&&!defined(tahoe)
111 	if (x != x)				/* NaN */
112 		return (x);
113 #endif	/* !defined(vax)&&!defined(tahoe) */
114 	if (copysign(x,one) >= L)		/* already an integer */
115 	    return (x);
116 	s = copysign(L,x);
117 	t = x + s;				/* x+s rounded to integer */
118 	return (t - s);
119 }
120 #endif	/* not national */
121