PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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
29
30/*
31 * Utility functions in float.c
32 */
33pg_noreturn extern void float_overflow_error(void);
34pg_noreturn extern void float_underflow_error(void);
35pg_noreturn extern void float_zero_divide_error(void);
36extern float8 float_overflow_error_ext(struct Node *escontext);
37extern float8 float_underflow_error_ext(struct Node *escontext);
38extern float8 float_zero_divide_error_ext(struct Node *escontext);
39extern int is_infinite(float8 val);
40extern float8 float8in_internal(char *num, char **endptr_p,
41 const char *type_name, const char *orig_string,
42 struct Node *escontext);
43extern float4 float4in_internal(char *num, char **endptr_p,
44 const char *type_name, const char *orig_string,
45 struct Node *escontext);
46extern char *float8out_internal(float8 num);
49
50/*
51 * Postgres requires IEEE-standard float arithmetic, including infinities
52 * and NaNs. We used to support pre-C99 compilers on which <math.h> might
53 * not supply the standard macros INFINITY and NAN. We no longer do so,
54 * but these wrapper functions are still preferred over using those macros
55 * directly.
56 *
57 * If you change these functions, see copies in interfaces/ecpg/ecpglib/data.c.
58 */
59
60static inline float4
62{
63 /* C99 standard way */
64 return (float4) INFINITY;
65}
66
67static inline float8
69{
70 /* C99 standard way */
71 return (float8) INFINITY;
72}
73
74/* The C standard allows implementations to omit NAN, but we don't */
75#ifndef NAN
76#error "Postgres requires support for IEEE quiet NaNs"
77#endif
78
79static inline float4
81{
82 /* C99 standard way */
83 return (float4) NAN;
84}
85
86static inline float8
88{
89 /* C99 standard way */
90 return (float8) NAN;
91}
92
93/*
94 * Floating-point arithmetic with overflow/underflow reported as errors
95 *
96 * There isn't any way to check for underflow of addition/subtraction
97 * because numbers near the underflow value have already been rounded to
98 * the point where we can't detect that the two values were originally
99 * different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 ==
100 * 1.4013e-45.
101 */
102
103static inline float4
105{
107
108 result = val1 + val2;
109 if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
111
112 return result;
113}
114
115static inline float8
116float8_pl_safe(const float8 val1, const float8 val2, struct Node *escontext)
117{
119
120 result = val1 + val2;
121 if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
122 return float_overflow_error_ext(escontext);
123
124 return result;
125}
126
127static inline float8
129{
130 return float8_pl_safe(val1, val2, NULL);
131}
132
133static inline float4
135{
137
138 result = val1 - val2;
139 if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
141
142 return result;
143}
144
145static inline float8
146float8_mi_safe(const float8 val1, const float8 val2, struct Node *escontext)
147{
149
150 result = val1 - val2;
151 if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
152 return float_overflow_error_ext(escontext);
153
154 return result;
155}
156
157static inline float8
159{
160 return float8_mi_safe(val1, val2, NULL);
161}
162
163static inline float4
165{
167
168 result = val1 * val2;
169 if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
171 if (unlikely(result == 0.0f) && val1 != 0.0f && val2 != 0.0f)
173
174 return result;
175}
176
177static inline float8
178float8_mul_safe(const float8 val1, const float8 val2, struct Node *escontext)
179{
181
182 result = val1 * val2;
183 if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
184 return float_overflow_error_ext(escontext);
185 if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0)
186 return float_underflow_error_ext(escontext);
187
188 return result;
189}
190
191static inline float8
193{
194 return float8_mul_safe(val1, val2, NULL);
195}
196
197static inline float4
199{
201
202 if (unlikely(val2 == 0.0f) && !isnan(val1))
204 result = val1 / val2;
205 if (unlikely(isinf(result)) && !isinf(val1))
207 if (unlikely(result == 0.0f) && val1 != 0.0f && !isinf(val2))
209
210 return result;
211}
212
213static inline float8
214float8_div_safe(const float8 val1, const float8 val2, struct Node *escontext)
215{
217
218 if (unlikely(val2 == 0.0) && !isnan(val1))
219 return float_zero_divide_error_ext(escontext);
220 result = val1 / val2;
221 if (unlikely(isinf(result)) && !isinf(val1))
222 return float_overflow_error_ext(escontext);
223 if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2))
224 return float_underflow_error_ext(escontext);
225
226 return result;
227}
228
229static inline float8
231{
232 return float8_div_safe(val1, val2, NULL);
233}
234
235/*
236 * Routines for NaN-aware comparisons
237 *
238 * We consider all NaNs to be equal and larger than any non-NaN. This is
239 * somewhat arbitrary; the important thing is to have a consistent sort
240 * order.
241 */
242
243static inline bool
245{
246 return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
247}
248
249static inline bool
251{
252 return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
253}
254
255static inline bool
257{
258 return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
259}
260
261static inline bool
263{
264 return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
265}
266
267static inline bool
269{
270 return !isnan(val1) && (isnan(val2) || val1 < val2);
271}
272
273static inline bool
275{
276 return !isnan(val1) && (isnan(val2) || val1 < val2);
277}
278
279static inline bool
281{
282 return isnan(val2) || (!isnan(val1) && val1 <= val2);
283}
284
285static inline bool
287{
288 return isnan(val2) || (!isnan(val1) && val1 <= val2);
289}
290
291static inline bool
293{
294 return !isnan(val2) && (isnan(val1) || val1 > val2);
295}
296
297static inline bool
299{
300 return !isnan(val2) && (isnan(val1) || val1 > val2);
301}
302
303static inline bool
305{
306 return isnan(val1) || (!isnan(val2) && val1 >= val2);
307}
308
309static inline bool
311{
312 return isnan(val1) || (!isnan(val2) && val1 >= val2);
313}
314
315static inline float4
317{
318 return float4_lt(val1, val2) ? val1 : val2;
319}
320
321static inline float8
323{
324 return float8_lt(val1, val2) ? val1 : val2;
325}
326
327static inline float4
329{
330 return float4_gt(val1, val2) ? val1 : val2;
331}
332
333static inline float8
335{
336 return float8_gt(val1, val2) ? val1 : val2;
337}
338
339#endif /* FLOAT_H */
#define PGDLLIMPORT
Definition c.h:1421
#define pg_noreturn
Definition c.h:190
double float8
Definition c.h:714
#define unlikely(x)
Definition c.h:438
float float4
Definition c.h:713
uint32 result
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:436
float8 float_underflow_error_ext(struct Node *escontext)
Definition float.c:135
static float8 float8_mul_safe(const float8 val1, const float8 val2, struct Node *escontext)
Definition float.h:178
static float8 float8_min(const float8 val1, const float8 val2)
Definition float.h:322
static float8 float8_pl_safe(const float8 val1, const float8 val2, struct Node *escontext)
Definition float.h:116
static float8 float8_mul(const float8 val1, const float8 val2)
Definition float.h:192
static float4 float4_div(const float4 val1, const float4 val2)
Definition float.h:198
static float4 get_float4_infinity(void)
Definition float.h:61
pg_noreturn void float_overflow_error(void)
Definition float.c:103
PGDLLIMPORT int extra_float_digits
Definition float.c:57
static bool float4_lt(const float4 val1, const float4 val2)
Definition float.h:268
static float8 float8_pl(const float8 val1, const float8 val2)
Definition float.h:128
static float8 float8_mi(const float8 val1, const float8 val2)
Definition float.h:158
static bool float4_ge(const float4 val1, const float4 val2)
Definition float.h:304
static float4 get_float4_nan(void)
Definition float.h:80
int is_infinite(float8 val)
Definition float.c:159
static bool float8_ne(const float8 val1, const float8 val2)
Definition float.h:262
static bool float4_ne(const float4 val1, const float4 val2)
Definition float.h:256
static float4 float4_pl(const float4 val1, const float4 val2)
Definition float.h:104
static float4 float4_max(const float4 val1, const float4 val2)
Definition float.h:328
static bool float4_eq(const float4 val1, const float4 val2)
Definition float.h:244
static float4 float4_mul(const float4 val1, const float4 val2)
Definition float.h:164
pg_noreturn void float_underflow_error(void)
Definition float.c:111
static float8 get_float8_infinity(void)
Definition float.h:68
static bool float8_ge(const float8 val1, const float8 val2)
Definition float.h:310
int float4_cmp_internal(float4 a, float4 b)
Definition float.c:857
char * float8out_internal(float8 num)
Definition float.c:578
static float8 float8_mi_safe(const float8 val1, const float8 val2, struct Node *escontext)
Definition float.h:146
float8 float_overflow_error_ext(struct Node *escontext)
Definition float.c:127
float4 float4in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:224
static float4 float4_mi(const float4 val1, const float4 val2)
Definition float.h:134
static float8 float8_max(const float8 val1, const float8 val2)
Definition float.h:334
static bool float8_le(const float8 val1, const float8 val2)
Definition float.h:286
static bool float4_gt(const float4 val1, const float4 val2)
Definition float.h:292
static bool float8_eq(const float8 val1, const float8 val2)
Definition float.h:250
static float4 float4_min(const float4 val1, const float4 val2)
Definition float.h:316
static bool float4_le(const float4 val1, const float4 val2)
Definition float.h:280
static float8 get_float8_nan(void)
Definition float.h:87
static float8 float8_div(const float8 val1, const float8 val2)
Definition float.h:230
pg_noreturn void float_zero_divide_error(void)
Definition float.c:119
static float8 float8_div_safe(const float8 val1, const float8 val2, struct Node *escontext)
Definition float.h:214
static bool float8_lt(const float8 val1, const float8 val2)
Definition float.h:274
static bool float8_gt(const float8 val1, const float8 val2)
Definition float.h:298
float8 float_zero_divide_error_ext(struct Node *escontext)
Definition float.c:143
int float8_cmp_internal(float8 a, float8 b)
Definition float.c:951
long val
Definition informix.c:689
int b
Definition isn.c:74
int a
Definition isn.c:73
static int fb(int x)
Definition nodes.h:135