xref: /csrg-svn/lib/libm/common_source/floor.c (revision 34122)
1 /*
2  * Copyright (c) 1985 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)floor.c	5.2 (Berkeley) 04/29/88";
9 #endif /* not lint */
10 
11 /*
12  * floor and ceil-- greatest integer <= arg
13  * (resp least >=)
14  */
15 
16 double	modf();
17 
18 double
19 floor(d)
20 double d;
21 {
22 	double fract;
23 
24 	if (d<0.0) {
25 		d = -d;
26 		fract = modf(d, &d);
27 		if (fract != 0.0)
28 			d += 1;
29 		d = -d;
30 	} else
31 		modf(d, &d);
32 	return(d);
33 }
34 
35 double
36 ceil(d)
37 double d;
38 {
39 	return(-floor(-d));
40 }
41 
42 #ifndef national			/* rint() is in ./NATIONAL/support.s */
43 /*
44  * algorithm for rint(x) in pseudo-pascal form ...
45  *
46  * real rint(x): real x;
47  *	... delivers integer nearest x in direction of prevailing rounding
48  *	... mode
49  * const	L = (last consecutive integer)/2
50  * 	  = 2**55; for VAX D
51  * 	  = 2**52; for IEEE 754 Double
52  * real	s,t;
53  * begin
54  * 	if x != x then return x;		... NaN
55  * 	if |x| >= L then return x;		... already an integer
56  * 	s := copysign(L,x);
57  * 	t := x + s;				... = (x+s) rounded to integer
58  * 	return t - s
59  * end;
60  *
61  * Note: Inexact will be signaled if x is not an integer, as is
62  *	customary for IEEE 754.  No other signal can be emitted.
63  */
64 #if defined(vax)||defined(tahoe)
65 #ifdef vax
66 #define _0x(A,B)	0x/**/A/**/B
67 #else	/* vax */
68 #define _0x(A,B)	0x/**/B/**/A
69 #endif	/* vax */
70 static long Lx[] = {_0x(0000,5c00),_0x(0000,0000)};	/* 2**55 */
71 #define L *(double *) Lx
72 #else	/* defined(vax)||defined(tahoe) */
73 static double L = 4503599627370496.0E0;		/* 2**52 */
74 #endif	/* defined(vax)||defined(tahoe) */
75 double
76 rint(x)
77 double x;
78 {
79 	double s,t,one = 1.0,copysign();
80 #if !defined(vax)&&!defined(tahoe)
81 	if (x != x)				/* NaN */
82 		return (x);
83 #endif	/* !defined(vax)&&!defined(tahoe) */
84 	if (copysign(x,one) >= L)		/* already an integer */
85 	    return (x);
86 	s = copysign(L,x);
87 	t = x + s;				/* x+s rounded to integer */
88 	return (t - s);
89 }
90 #endif	/* not national */
91