This source file includes following definitions.
- FLOOR_BASED_ROUND
- FLOOR_FREE_ROUND
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #if ! defined USE_LONG_DOUBLE
21 # include <config.h>
22 #endif
23
24
25 #include <math.h>
26
27 #include <float.h>
28
29 #undef MIN
30
31 #ifdef USE_LONG_DOUBLE
32 # define ROUND roundl
33 # define FLOOR floorl
34 # define CEIL ceill
35 # define DOUBLE long double
36 # define MANT_DIG LDBL_MANT_DIG
37 # define MIN LDBL_MIN
38 # define L_(literal) literal##L
39 # define HAVE_FLOOR_AND_CEIL HAVE_FLOORL_AND_CEILL
40 #elif ! defined USE_FLOAT
41 # define ROUND round
42 # define FLOOR floor
43 # define CEIL ceil
44 # define DOUBLE double
45 # define MANT_DIG DBL_MANT_DIG
46 # define MIN DBL_MIN
47 # define L_(literal) literal
48 # define HAVE_FLOOR_AND_CEIL 1
49 #else
50 # define ROUND roundf
51 # define FLOOR floorf
52 # define CEIL ceilf
53 # define DOUBLE float
54 # define MANT_DIG FLT_MANT_DIG
55 # define MIN FLT_MIN
56 # define L_(literal) literal##f
57 # define HAVE_FLOOR_AND_CEIL HAVE_FLOORF_AND_CEILF
58 #endif
59
60
61 #if defined __hpux || defined __sgi || defined __ICC
62 # define MINUS_ZERO (-MIN * MIN)
63 #else
64 # define MINUS_ZERO L_(-0.0)
65 #endif
66
67
68
69 #if defined _MSC_VER && !defined __clang__
70 # pragma fenv_access (off)
71 #endif
72
73
74
75
76 #if !defined FLOOR_BASED_ROUND && !defined FLOOR_FREE_ROUND
77 # if HAVE_FLOOR_AND_CEIL
78 # define FLOOR_BASED_ROUND ROUND
79 # else
80 # define FLOOR_FREE_ROUND ROUND
81 # endif
82 #endif
83
84 #ifdef FLOOR_BASED_ROUND
85
86
87
88 DOUBLE
89 FLOOR_BASED_ROUND (DOUBLE x)
90 {
91 if (x >= L_(0.0))
92 {
93 DOUBLE y = FLOOR (x);
94 if (x - y >= L_(0.5))
95 y += L_(1.0);
96 return y;
97 }
98 else
99 {
100 DOUBLE y = CEIL (x);
101 if (y - x >= L_(0.5))
102 y -= L_(1.0);
103 return y;
104 }
105 }
106 #endif
107
108 #ifdef FLOOR_FREE_ROUND
109
110
111 DOUBLE
112 FLOOR_FREE_ROUND (DOUBLE x)
113 {
114
115 static const DOUBLE TWO_MANT_DIG =
116
117
118
119 (DOUBLE) (1U << ((MANT_DIG - 1) / 5))
120 * (DOUBLE) (1U << ((MANT_DIG - 1 + 1) / 5))
121 * (DOUBLE) (1U << ((MANT_DIG - 1 + 2) / 5))
122 * (DOUBLE) (1U << ((MANT_DIG - 1 + 3) / 5))
123 * (DOUBLE) (1U << ((MANT_DIG - 1 + 4) / 5));
124
125
126
127
128
129
130
131 volatile DOUBLE y = x;
132 volatile DOUBLE z = y;
133
134 if (z > L_(0.0))
135 {
136
137 if (z < L_(0.5))
138 z = L_(0.0);
139
140 else if (z < TWO_MANT_DIG)
141 {
142
143 y = z += L_(0.5);
144
145
146 z += TWO_MANT_DIG;
147 z -= TWO_MANT_DIG;
148
149 if (z > y)
150 z -= L_(1.0);
151 }
152 }
153 else if (z < L_(0.0))
154 {
155
156 if (z > - L_(0.5))
157 z = MINUS_ZERO;
158
159 else if (z > -TWO_MANT_DIG)
160 {
161
162 y = z -= L_(0.5);
163
164
165 z -= TWO_MANT_DIG;
166 z += TWO_MANT_DIG;
167
168 if (z < y)
169 z += L_(1.0);
170 }
171 }
172 return z;
173 }
174 #endif