1
2 /* @(#)s_floor.c 5.1 93/09/24 */
3 /*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 *
7 * Developed at SunPro, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 */
13
14 /*
15 FUNCTION
16 <<floor>>, <<floorf>>, <<ceil>>, <<ceilf>>---floor and ceiling
17 INDEX
18 floor
19 INDEX
20 floorf
21 INDEX
22 ceil
23 INDEX
24 ceilf
25
26 SYNOPSIS
27 #include <math.h>
28 double floor(double <[x]>);
29 float floorf(float <[x]>);
30 double ceil(double <[x]>);
31 float ceilf(float <[x]>);
32
33 DESCRIPTION
34 <<floor>> and <<floorf>> find
35 @tex
36 $\lfloor x \rfloor$,
37 @end tex
38 the nearest integer less than or equal to <[x]>.
39 <<ceil>> and <<ceilf>> find
40 @tex
41 $\lceil x\rceil$,
42 @end tex
43 the nearest integer greater than or equal to <[x]>.
44
45 RETURNS
46 <<floor>> and <<ceil>> return the integer result as a double.
47 <<floorf>> and <<ceilf>> return the integer result as a float.
48
49 PORTABILITY
50 <<floor>> and <<ceil>> are ANSI.
51 <<floorf>> and <<ceilf>> are extensions.
52
53
54 */
55
56 /*
57 * floor(x)
58 * Return x rounded toward -inf to integral value
59 * Method:
60 * Bit twiddling.
61 * Exception:
62 * Inexact flag raised if x not equal to floor(x).
63 */
64
65 #include "fdlibm.h"
66
67 #ifdef _NEED_FLOAT64
68
69 __float64
floor64(__float64 x)70 floor64(__float64 x)
71 {
72 __int32_t i0, i1, j0, j;
73 __uint32_t i;
74 EXTRACT_WORDS(i0, i1, x);
75 j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
76 if (j0 < 20) {
77 if (j0 < 0) {
78 if (i0 >= 0) {
79 i0 = i1 = 0;
80 } else if (((i0 & 0x7fffffff) | i1) != 0) {
81 i0 = 0xbff00000;
82 i1 = 0;
83 }
84 } else {
85 i = (0x000fffff) >> j0;
86 if (((i0 & i) | i1) == 0)
87 return x; /* x is integral */
88 if (i0 < 0)
89 i0 += (0x00100000) >> j0;
90 i0 &= (~i);
91 i1 = 0;
92 }
93 } else if (j0 > 51) {
94 if (j0 == 0x400)
95 return x + x; /* inf or NaN */
96 else
97 return x; /* x is integral */
98 } else {
99 i = ((__uint32_t)(0xffffffff)) >> (j0 - 20);
100 if ((i1 & i) == 0)
101 return x; /* x is integral */
102 if (i0 < 0) {
103 if (j0 == 20)
104 i0 += 1;
105 else {
106 j = i1 + ((__uint32_t) 1 << (52 - j0));
107 if ((__uint32_t) j < (__uint32_t) i1)
108 i0 += 1; /* got a carry */
109 i1 = j;
110 }
111 }
112 i1 &= (~i);
113 }
114 INSERT_WORDS(x, i0, i1);
115 return x;
116 }
117
118 _MATH_ALIAS_d_d(floor)
119
120 #endif /* _NEED_FLOAT64 */
121