xref: /original-bsd/lib/libm/common_source/floor.c (revision e718337e)
1 /*
2  * Copyright (c) 1985 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)floor.c	5.7 (Berkeley) 10/09/90";
10 #endif /* not lint */
11 
12 #include "mathimpl.h"
13 
14 vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
15 
16 ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
17 
18 #ifdef vccast
19 #define	L	vccast(L)
20 #endif
21 
22 
23 double ceil();
24 double floor();
25 
26 /*
27  * floor(x) := the largest integer no larger than x;
28  * ceil(x) := -floor(-x), for all real x.
29  *
30  * Note: Inexact will be signaled if x is not an integer, as is
31  *	customary for IEEE 754.  No other signal can be emitted.
32  */
33 double
34 floor(x)
35 double x;
36 {
37 	double y;
38 
39 	if (
40 #if !defined(vax)&&!defined(tahoe)
41 		x != x ||	/* NaN */
42 #endif	/* !defined(vax)&&!defined(tahoe) */
43 		x >= L)		/* already an even integer */
44 		return x;
45 	else if (x < (double)0)
46 		return -ceil(-x);
47 	else {			/* now 0 <= x < L */
48 		y = L+x;		/* destructive store must be forced */
49 		y -= L;			/* an integer, and |x-y| < 1 */
50 		return x < y ? y-(double)1 : y;
51 	}
52 }
53 
54 double
55 ceil(x)
56 double x;
57 {
58 	double y;
59 
60 	if (
61 #if !defined(vax)&&!defined(tahoe)
62 		x != x ||	/* NaN */
63 #endif	/* !defined(vax)&&!defined(tahoe) */
64 		x >= L)		/* already an even integer */
65 		return x;
66 	else if (x < (double)0)
67 		return -floor(-x);
68 	else {			/* now 0 <= x < L */
69 		y = L+x;		/* destructive store must be forced */
70 		y -= L;			/* an integer, and |x-y| < 1 */
71 		return x > y ? y+(double)1 : y;
72 	}
73 }
74 
75 #ifndef national			/* rint() is in ./NATIONAL/support.s */
76 /*
77  * algorithm for rint(x) in pseudo-pascal form ...
78  *
79  * real rint(x): real x;
80  *	... delivers integer nearest x in direction of prevailing rounding
81  *	... mode
82  * const	L = (last consecutive integer)/2
83  * 	  = 2**55; for VAX D
84  * 	  = 2**52; for IEEE 754 Double
85  * real	s,t;
86  * begin
87  * 	if x != x then return x;		... NaN
88  * 	if |x| >= L then return x;		... already an integer
89  * 	s := copysign(L,x);
90  * 	t := x + s;				... = (x+s) rounded to integer
91  * 	return t - s
92  * end;
93  *
94  * Note: Inexact will be signaled if x is not an integer, as is
95  *	customary for IEEE 754.  No other signal can be emitted.
96  */
97 double
98 rint(x)
99 double x;
100 {
101 	double s,t;
102 	const double one = 1.0;
103 
104 #if !defined(vax)&&!defined(tahoe)
105 	if (x != x)				/* NaN */
106 		return (x);
107 #endif	/* !defined(vax)&&!defined(tahoe) */
108 	if (copysign(x,one) >= L)		/* already an integer */
109 	    return (x);
110 	s = copysign(L,x);
111 	t = x + s;				/* x+s rounded to integer */
112 	return (t - s);
113 }
114 #endif	/* not national */
115