PostgreSQL Source Code  git master
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-2020, 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)
30 static 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  */
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 extern float8 float8in_internal_opt_error(char *num, char **endptr_p,
47  const char *type_name, const char *orig_string,
48  bool *have_error);
49 extern char *float8out_internal(float8 num);
50 extern int float4_cmp_internal(float4 a, float4 b);
51 extern 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
72 static 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 
92 static 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 
109 static 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 
121 static 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 
144 static inline float4
145 float4_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 
156 static inline float8
157 float8_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 
168 static inline float4
169 float4_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 
180 static inline float8
181 float8_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 
192 static inline float4
193 float4_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 
206 static inline float8
207 float8_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 
220 static inline float4
221 float4_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 
236 static inline float8
237 float8_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 
260 static inline bool
261 float4_eq(const float4 val1, const float4 val2)
262 {
263  return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
264 }
265 
266 static inline bool
267 float8_eq(const float8 val1, const float8 val2)
268 {
269  return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
270 }
271 
272 static inline bool
273 float4_ne(const float4 val1, const float4 val2)
274 {
275  return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
276 }
277 
278 static inline bool
279 float8_ne(const float8 val1, const float8 val2)
280 {
281  return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
282 }
283 
284 static inline bool
285 float4_lt(const float4 val1, const float4 val2)
286 {
287  return !isnan(val1) && (isnan(val2) || val1 < val2);
288 }
289 
290 static inline bool
291 float8_lt(const float8 val1, const float8 val2)
292 {
293  return !isnan(val1) && (isnan(val2) || val1 < val2);
294 }
295 
296 static inline bool
297 float4_le(const float4 val1, const float4 val2)
298 {
299  return isnan(val2) || (!isnan(val1) && val1 <= val2);
300 }
301 
302 static inline bool
303 float8_le(const float8 val1, const float8 val2)
304 {
305  return isnan(val2) || (!isnan(val1) && val1 <= val2);
306 }
307 
308 static inline bool
309 float4_gt(const float4 val1, const float4 val2)
310 {
311  return !isnan(val2) && (isnan(val1) || val1 > val2);
312 }
313 
314 static inline bool
315 float8_gt(const float8 val1, const float8 val2)
316 {
317  return !isnan(val2) && (isnan(val1) || val1 > val2);
318 }
319 
320 static inline bool
321 float4_ge(const float4 val1, const float4 val2)
322 {
323  return isnan(val1) || (!isnan(val2) && val1 >= val2);
324 }
325 
326 static inline bool
327 float8_ge(const float8 val1, const float8 val2)
328 {
329  return isnan(val1) || (!isnan(val2) && val1 >= val2);
330 }
331 
332 static inline float4
333 float4_min(const float4 val1, const float4 val2)
334 {
335  return float4_lt(val1, val2) ? val1 : val2;
336 }
337 
338 static inline float8
339 float8_min(const float8 val1, const float8 val2)
340 {
341  return float8_lt(val1, val2) ? val1 : val2;
342 }
343 
344 static inline float4
345 float4_max(const float4 val1, const float4 val2)
346 {
347  return float4_gt(val1, val2) ? val1 : val2;
348 }
349 
350 static inline float8
351 float8_max(const float8 val1, const float8 val2)
352 {
353  return float8_gt(val1, val2) ? val1 : val2;
354 }
355 
356 #endif /* FLOAT_H */
static bool float8_ne(const float8 val1, const float8 val2)
Definition: float.h:279
#define pg_attribute_noreturn()
Definition: c.h:167
PGDLLIMPORT int extra_float_digits
Definition: float.c:42
static float4 float4_div(const float4 val1, const float4 val2)
Definition: float.h:221
int float8_cmp_internal(float8 a, float8 b)
Definition: float.c:914
static float8 get_float8_infinity(void)
Definition: float.h:93
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string)
Definition: float.c:513
static float8 float8_min(const float8 val1, const float8 val2)
Definition: float.h:339
static bool float8_le(const float8 val1, const float8 val2)
Definition: float.h:303
static float8 float8_mul(const float8 val1, const float8 val2)
Definition: float.h:207
#define PGDLLIMPORT
Definition: c.h:1313
void float_zero_divide_error(void) pg_attribute_noreturn()
Definition: float.c:100
static float4 float4_mi(const float4 val1, const float4 val2)
Definition: float.h:169
double float8
Definition: c.h:553
static float8 get_float8_nan(void)
Definition: float.h:122
int is_infinite(float8 val)
Definition: float.c:116
static bool float8_ge(const float8 val1, const float8 val2)
Definition: float.h:327
unsigned int uint32
Definition: c.h:429
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 float4 float4_min(const float4 val1, const float4 val2)
Definition: float.h:333
char * float8out_internal(float8 num)
Definition: float.c:541
static bool float4_gt(const float4 val1, const float4 val2)
Definition: float.h:309
static bool float8_lt(const float8 val1, const float8 val2)
Definition: float.h:291
static float4 get_float4_nan(void)
Definition: float.h:110
float8 float8in_internal_opt_error(char *num, char **endptr_p, const char *type_name, const char *orig_string, bool *have_error)
Definition: float.c:379
float float4
Definition: c.h:552
static bool float4_lt(const float4 val1, const float4 val2)
Definition: float.h:285
static bool float8_gt(const float8 val1, const float8 val2)
Definition: float.h:315
static bool float4_ge(const float4 val1, const float4 val2)
Definition: float.h:321
static bool float4_ne(const float4 val1, const float4 val2)
Definition: float.h:273
int float4_cmp_internal(float4 a, float4 b)
Definition: float.c:820
void float_overflow_error(void) pg_attribute_noreturn()
Definition: float.c:84
static float8 float8_div(const float8 val1, const float8 val2)
Definition: float.h:237
static bool float4_eq(const float4 val1, const float4 val2)
Definition: float.h:261
static bool float8_eq(const float8 val1, const float8 val2)
Definition: float.h:267
void float_underflow_error(void) pg_attribute_noreturn()
Definition: float.c:92
static bool float4_le(const float4 val1, const float4 val2)
Definition: float.h:297
static float4 float4_pl(const float4 val1, const float4 val2)
Definition: float.h:145
static float4 float4_mul(const float4 val1, const float4 val2)
Definition: float.h:193
#define unlikely(x)
Definition: c.h:261
static float8 float8_max(const float8 val1, const float8 val2)
Definition: float.h:351
long val
Definition: informix.c:664
static float4 float4_max(const float4 val1, const float4 val2)
Definition: float.h:345
static float4 get_float4_infinity(void)
Definition: float.h:73