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