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