TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * float.h
4 : * Definitions for the built-in floating-point types
5 : *
6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/include/utils/float.h
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 : #ifndef FLOAT_H
16 : #define FLOAT_H
17 :
18 : #include <math.h>
19 :
20 : /* X/Open (XSI) requires <math.h> to provide M_PI, but core POSIX does not */
21 : #ifndef M_PI
22 : #define M_PI 3.14159265358979323846
23 : #endif
24 :
25 : /* Radians per degree, a.k.a. PI / 180 */
26 : #define RADIANS_PER_DEGREE 0.0174532925199432957692
27 :
28 : /* Visual C++ etc lacks NAN, and won't accept 0.0/0.0. */
29 : #if defined(WIN32) && !defined(NAN)
30 : static const uint32 nan[2] = {0xffffffff, 0x7fffffff};
31 :
32 : #define NAN (*(const float8 *) nan)
33 : #endif
34 :
35 : extern PGDLLIMPORT int extra_float_digits;
36 :
37 : /*
38 : * Utility functions in float.c
39 : */
40 : extern void float_overflow_error(void) pg_attribute_noreturn();
41 : extern void float_underflow_error(void) pg_attribute_noreturn();
42 : extern void float_zero_divide_error(void) pg_attribute_noreturn();
43 : extern int is_infinite(float8 val);
44 : extern float8 float8in_internal(char *num, char **endptr_p,
45 : const char *type_name, const char *orig_string,
46 : struct Node *escontext);
47 : extern float4 float4in_internal(char *num, char **endptr_p,
48 : const char *type_name, const char *orig_string,
49 : struct Node *escontext);
50 : extern char *float8out_internal(float8 num);
51 : extern int float4_cmp_internal(float4 a, float4 b);
52 : extern int float8_cmp_internal(float8 a, float8 b);
53 :
54 : /*
55 : * Routines to provide reasonably platform-independent handling of
56 : * infinity and NaN
57 : *
58 : * We assume that isinf() and isnan() are available and work per spec.
59 : * (On some platforms, we have to supply our own; see src/port.) However,
60 : * generating an Infinity or NaN in the first place is less well standardized;
61 : * pre-C99 systems tend not to have C99's INFINITY and NaN macros. We
62 : * centralize our workarounds for this here.
63 : */
64 :
65 : /*
66 : * The funny placements of the two #pragmas is necessary because of a
67 : * long lived bug in the Microsoft compilers.
68 : * See http://support.microsoft.com/kb/120968/en-us for details
69 : */
70 : #ifdef _MSC_VER
71 : #pragma warning(disable:4756)
72 : #endif
73 : static inline float4
74 GIC 207542 : get_float4_infinity(void)
75 ECB : {
76 : #ifdef INFINITY
77 : /* C99 standard way */
78 GIC 207542 : return (float4) INFINITY;
79 ECB : #else
80 : #ifdef _MSC_VER
81 : #pragma warning(default:4756)
82 : #endif
83 :
84 : /*
85 : * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
86 : * largest normal float8. We assume forcing an overflow will get us a
87 : * true infinity.
88 : */
89 : return (float4) (HUGE_VAL * HUGE_VAL);
90 : #endif
91 : }
92 :
93 : static inline float8
94 GIC 753921 : get_float8_infinity(void)
95 ECB : {
96 : #ifdef INFINITY
97 : /* C99 standard way */
98 GIC 753921 : return (float8) INFINITY;
99 ECB : #else
100 :
101 : /*
102 : * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
103 : * largest normal float8. We assume forcing an overflow will get us a
104 : * true infinity.
105 : */
106 : return (float8) (HUGE_VAL * HUGE_VAL);
107 : #endif
108 : }
109 :
110 : static inline float4
111 GIC 15 : get_float4_nan(void)
112 ECB : {
113 : #ifdef NAN
114 : /* C99 standard way */
115 GIC 15 : return (float4) NAN;
116 ECB : #else
117 : /* Assume we can get a NAN via zero divide */
118 : return (float4) (0.0 / 0.0);
119 : #endif
120 : }
121 :
122 : static inline float8
123 GIC 10866 : get_float8_nan(void)
124 ECB : {
125 : /* (float8) NAN doesn't work on some NetBSD/MIPS releases */
126 : #if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__))
127 : /* C99 standard way */
128 GIC 10866 : return (float8) NAN;
129 ECB : #else
130 : /* Assume we can get a NaN via zero divide */
131 : return (float8) (0.0 / 0.0);
132 : #endif
133 : }
134 :
135 : /*
136 : * Floating-point arithmetic with overflow/underflow reported as errors
137 : *
138 : * There isn't any way to check for underflow of addition/subtraction
139 : * because numbers near the underflow value have already been rounded to
140 : * the point where we can't detect that the two values were originally
141 : * different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 ==
142 : * 1.4013e-45.
143 : */
144 :
145 : static inline float4
146 GIC 27 : float4_pl(const float4 val1, const float4 val2)
147 ECB : {
148 : float4 result;
149 :
150 GIC 27 : result = val1 + val2;
151 CBC 27 : if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
152 LBC 0 : float_overflow_error();
153 EUB :
154 GIC 27 : return result;
155 ECB : }
156 :
157 : static inline float8
158 GIC 2866988 : float8_pl(const float8 val1, const float8 val2)
159 ECB : {
160 : float8 result;
161 :
162 GIC 2866988 : result = val1 + val2;
163 CBC 2866988 : if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
164 LBC 0 : float_overflow_error();
165 EUB :
166 GIC 2866988 : return result;
167 ECB : }
168 :
169 : static inline float4
170 GIC 9 : float4_mi(const float4 val1, const float4 val2)
171 ECB : {
172 : float4 result;
173 :
174 GIC 9 : result = val1 - val2;
175 CBC 9 : if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
176 LBC 0 : float_overflow_error();
177 EUB :
178 GIC 9 : return result;
179 ECB : }
180 :
181 : static inline float8
182 GIC 130288673 : float8_mi(const float8 val1, const float8 val2)
183 ECB : {
184 : float8 result;
185 :
186 GIC 130288673 : result = val1 - val2;
187 CBC 130288673 : if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
188 LBC 0 : float_overflow_error();
189 EUB :
190 GIC 130288673 : return result;
191 ECB : }
192 :
193 : static inline float4
194 GIC 18 : float4_mul(const float4 val1, const float4 val2)
195 ECB : {
196 : float4 result;
197 :
198 GIC 18 : result = val1 * val2;
199 CBC 18 : if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
200 LBC 0 : float_overflow_error();
201 GBC 18 : if (unlikely(result == 0.0f) && val1 != 0.0f && val2 != 0.0f)
202 LBC 0 : float_underflow_error();
203 EUB :
204 GIC 18 : return result;
205 ECB : }
206 :
207 : static inline float8
208 GIC 56153160 : float8_mul(const float8 val1, const float8 val2)
209 ECB : {
210 : float8 result;
211 :
212 GIC 56153160 : result = val1 * val2;
213 CBC 56153160 : if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
214 9 : float_overflow_error();
215 56153151 : if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0)
216 3 : float_underflow_error();
217 ECB :
218 GIC 56153148 : return result;
219 ECB : }
220 :
221 : static inline float4
222 GIC 3525265 : float4_div(const float4 val1, const float4 val2)
223 ECB : {
224 : float4 result;
225 :
226 GIC 3525265 : if (unlikely(val2 == 0.0f) && !isnan(val1))
227 CBC 3 : float_zero_divide_error();
228 3525262 : result = val1 / val2;
229 3525262 : if (unlikely(isinf(result)) && !isinf(val1))
230 LBC 0 : float_overflow_error();
231 GBC 3525262 : if (unlikely(result == 0.0f) && val1 != 0.0f && !isinf(val2))
232 LBC 0 : float_underflow_error();
233 EUB :
234 GIC 3525262 : return result;
235 ECB : }
236 :
237 : static inline float8
238 GIC 9709887 : float8_div(const float8 val1, const float8 val2)
239 ECB : {
240 : float8 result;
241 :
242 GIC 9709887 : if (unlikely(val2 == 0.0) && !isnan(val1))
243 CBC 33 : float_zero_divide_error();
244 9709854 : result = val1 / val2;
245 9709854 : if (unlikely(isinf(result)) && !isinf(val1))
246 LBC 0 : float_overflow_error();
247 GBC 9709854 : if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2))
248 LBC 0 : float_underflow_error();
249 EUB :
250 GIC 9709854 : return result;
251 ECB : }
252 :
253 : /*
254 : * Routines for NaN-aware comparisons
255 : *
256 : * We consider all NaNs to be equal and larger than any non-NaN. This is
257 : * somewhat arbitrary; the important thing is to have a consistent sort
258 : * order.
259 : */
260 :
261 : static inline bool
262 GIC 31166 : float4_eq(const float4 val1, const float4 val2)
263 ECB : {
264 GIC 31166 : return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
265 ECB : }
266 :
267 : static inline bool
268 GIC 8464387 : float8_eq(const float8 val1, const float8 val2)
269 ECB : {
270 GIC 8464387 : return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
271 ECB : }
272 :
273 : static inline bool
274 GIC 15 : float4_ne(const float4 val1, const float4 val2)
275 ECB : {
276 GIC 15 : return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
277 ECB : }
278 :
279 : static inline bool
280 GIC 9912 : float8_ne(const float8 val1, const float8 val2)
281 ECB : {
282 GIC 9912 : return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
283 ECB : }
284 :
285 : static inline bool
286 GIC 24738422 : float4_lt(const float4 val1, const float4 val2)
287 ECB : {
288 GIC 24738422 : return !isnan(val1) && (isnan(val2) || val1 < val2);
289 ECB : }
290 :
291 : static inline bool
292 GIC 62399573 : float8_lt(const float8 val1, const float8 val2)
293 ECB : {
294 GIC 62399573 : return !isnan(val1) && (isnan(val2) || val1 < val2);
295 ECB : }
296 :
297 : static inline bool
298 GIC 1914 : float4_le(const float4 val1, const float4 val2)
299 ECB : {
300 GIC 1914 : return isnan(val2) || (!isnan(val1) && val1 <= val2);
301 ECB : }
302 :
303 : static inline bool
304 GIC 85143552 : float8_le(const float8 val1, const float8 val2)
305 ECB : {
306 GIC 85143552 : return isnan(val2) || (!isnan(val1) && val1 <= val2);
307 ECB : }
308 :
309 : static inline bool
310 GIC 25269094 : float4_gt(const float4 val1, const float4 val2)
311 ECB : {
312 GIC 25269094 : return !isnan(val2) && (isnan(val1) || val1 > val2);
313 ECB : }
314 :
315 : static inline bool
316 GIC 66649997 : float8_gt(const float8 val1, const float8 val2)
317 ECB : {
318 GIC 66649997 : return !isnan(val2) && (isnan(val1) || val1 > val2);
319 ECB : }
320 :
321 : static inline bool
322 GIC 1914 : float4_ge(const float4 val1, const float4 val2)
323 ECB : {
324 GIC 1914 : return isnan(val1) || (!isnan(val2) && val1 >= val2);
325 ECB : }
326 :
327 : static inline bool
328 GIC 4433507 : float8_ge(const float8 val1, const float8 val2)
329 ECB : {
330 GIC 4433507 : return isnan(val1) || (!isnan(val2) && val1 >= val2);
331 ECB : }
332 :
333 : static inline float4
334 : float4_min(const float4 val1, const float4 val2)
335 : {
336 : return float4_lt(val1, val2) ? val1 : val2;
337 : }
338 :
339 : static inline float8
340 GIC 46795660 : float8_min(const float8 val1, const float8 val2)
341 ECB : {
342 GIC 46795660 : return float8_lt(val1, val2) ? val1 : val2;
343 ECB : }
344 :
345 : static inline float4
346 : float4_max(const float4 val1, const float4 val2)
347 : {
348 : return float4_gt(val1, val2) ? val1 : val2;
349 : }
350 :
351 : static inline float8
352 GIC 46795660 : float8_max(const float8 val1, const float8 val2)
353 ECB : {
354 GIC 46795660 : return float8_gt(val1, val2) ? val1 : val2;
355 ECB : }
356 :
357 : #endif /* FLOAT_H */
|