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