LCOV - differential code coverage report
Current view: top level - src/include/utils - float.h (source / functions) Coverage Total Hit LBC GBC GIC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 88.6 % 88 78 10 3 60 15 7 53
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 26 26 26 26
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 88.6 % 88 78 10 3 60 15 7 53
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 50.0 % 52 26 26 26

 Age         Owner                  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
 1715 tomas.vondra               74 GIC      207542 : get_float4_infinity(void)
 1715 tomas.vondra               75 ECB             : {
                                 76                 : #ifdef INFINITY
                                 77                 :     /* C99 standard way */
 1715 tomas.vondra               78 GIC      207542 :     return (float4) INFINITY;
 1715 tomas.vondra               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
 1715 tomas.vondra               94 GIC      753921 : get_float8_infinity(void)
 1715 tomas.vondra               95 ECB             : {
                                 96                 : #ifdef INFINITY
                                 97                 :     /* C99 standard way */
 1715 tomas.vondra               98 GIC      753921 :     return (float8) INFINITY;
 1715 tomas.vondra               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
 1715 tomas.vondra              111 GIC          15 : get_float4_nan(void)
 1715 tomas.vondra              112 ECB             : {
                                113                 : #ifdef NAN
                                114                 :     /* C99 standard way */
 1715 tomas.vondra              115 GIC          15 :     return (float4) NAN;
 1715 tomas.vondra              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
 1715 tomas.vondra              123 GIC       10866 : get_float8_nan(void)
 1715 tomas.vondra              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 */
 1715 tomas.vondra              128 GIC       10866 :     return (float8) NAN;
 1715 tomas.vondra              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
 1715 tomas.vondra              146 GIC          27 : float4_pl(const float4 val1, const float4 val2)
 1715 tomas.vondra              147 ECB             : {
                                148                 :     float4      result;
                                149                 : 
 1715 tomas.vondra              150 GIC          27 :     result = val1 + val2;
 1151 tgl                       151 CBC          27 :     if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
 1151 tgl                       152 LBC           0 :         float_overflow_error();
 1715 tomas.vondra              153 EUB             : 
 1715 tomas.vondra              154 GIC          27 :     return result;
 1715 tomas.vondra              155 ECB             : }
                                156                 : 
                                157                 : static inline float8
 1715 tomas.vondra              158 GIC     2866988 : float8_pl(const float8 val1, const float8 val2)
 1715 tomas.vondra              159 ECB             : {
                                160                 :     float8      result;
                                161                 : 
 1715 tomas.vondra              162 GIC     2866988 :     result = val1 + val2;
 1151 tgl                       163 CBC     2866988 :     if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
 1151 tgl                       164 LBC           0 :         float_overflow_error();
 1715 tomas.vondra              165 EUB             : 
 1715 tomas.vondra              166 GIC     2866988 :     return result;
 1715 tomas.vondra              167 ECB             : }
                                168                 : 
                                169                 : static inline float4
 1715 tomas.vondra              170 GIC           9 : float4_mi(const float4 val1, const float4 val2)
 1715 tomas.vondra              171 ECB             : {
                                172                 :     float4      result;
                                173                 : 
 1715 tomas.vondra              174 GIC           9 :     result = val1 - val2;
 1151 tgl                       175 CBC           9 :     if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
 1151 tgl                       176 LBC           0 :         float_overflow_error();
 1715 tomas.vondra              177 EUB             : 
 1715 tomas.vondra              178 GIC           9 :     return result;
 1715 tomas.vondra              179 ECB             : }
                                180                 : 
                                181                 : static inline float8
 1715 tomas.vondra              182 GIC   130288673 : float8_mi(const float8 val1, const float8 val2)
 1715 tomas.vondra              183 ECB             : {
                                184                 :     float8      result;
                                185                 : 
 1715 tomas.vondra              186 GIC   130288673 :     result = val1 - val2;
 1151 tgl                       187 CBC   130288673 :     if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
 1151 tgl                       188 LBC           0 :         float_overflow_error();
 1715 tomas.vondra              189 EUB             : 
 1715 tomas.vondra              190 GIC   130288673 :     return result;
 1715 tomas.vondra              191 ECB             : }
                                192                 : 
                                193                 : static inline float4
 1715 tomas.vondra              194 GIC          18 : float4_mul(const float4 val1, const float4 val2)
 1715 tomas.vondra              195 ECB             : {
                                196                 :     float4      result;
                                197                 : 
 1715 tomas.vondra              198 GIC          18 :     result = val1 * val2;
 1151 tgl                       199 CBC          18 :     if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
 1151 tgl                       200 LBC           0 :         float_overflow_error();
 1151 tgl                       201 GBC          18 :     if (unlikely(result == 0.0f) && val1 != 0.0f && val2 != 0.0f)
 1151 tgl                       202 LBC           0 :         float_underflow_error();
 1715 tomas.vondra              203 EUB             : 
 1715 tomas.vondra              204 GIC          18 :     return result;
 1715 tomas.vondra              205 ECB             : }
                                206                 : 
                                207                 : static inline float8
 1715 tomas.vondra              208 GIC    56153160 : float8_mul(const float8 val1, const float8 val2)
 1715 tomas.vondra              209 ECB             : {
                                210                 :     float8      result;
                                211                 : 
 1715 tomas.vondra              212 GIC    56153160 :     result = val1 * val2;
 1151 tgl                       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();
 1715 tomas.vondra              217 ECB             : 
 1715 tomas.vondra              218 GIC    56153148 :     return result;
 1715 tomas.vondra              219 ECB             : }
                                220                 : 
                                221                 : static inline float4
 1715 tomas.vondra              222 GIC     3525265 : float4_div(const float4 val1, const float4 val2)
 1715 tomas.vondra              223 ECB             : {
                                224                 :     float4      result;
                                225                 : 
  993 tgl                       226 GIC     3525265 :     if (unlikely(val2 == 0.0f) && !isnan(val1))
 1151 tgl                       227 CBC           3 :         float_zero_divide_error();
 1715 tomas.vondra              228         3525262 :     result = val1 / val2;
  886 tgl                       229         3525262 :     if (unlikely(isinf(result)) && !isinf(val1))
 1151 tgl                       230 LBC           0 :         float_overflow_error();
  886 tgl                       231 GBC     3525262 :     if (unlikely(result == 0.0f) && val1 != 0.0f && !isinf(val2))
 1151 tgl                       232 LBC           0 :         float_underflow_error();
 1715 tomas.vondra              233 EUB             : 
 1715 tomas.vondra              234 GIC     3525262 :     return result;
 1715 tomas.vondra              235 ECB             : }
                                236                 : 
                                237                 : static inline float8
 1715 tomas.vondra              238 GIC     9709887 : float8_div(const float8 val1, const float8 val2)
 1715 tomas.vondra              239 ECB             : {
                                240                 :     float8      result;
                                241                 : 
  993 tgl                       242 GIC     9709887 :     if (unlikely(val2 == 0.0) && !isnan(val1))
 1151 tgl                       243 CBC          33 :         float_zero_divide_error();
 1715 tomas.vondra              244         9709854 :     result = val1 / val2;
  886 tgl                       245         9709854 :     if (unlikely(isinf(result)) && !isinf(val1))
 1151 tgl                       246 LBC           0 :         float_overflow_error();
  886 tgl                       247 GBC     9709854 :     if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2))
 1151 tgl                       248 LBC           0 :         float_underflow_error();
 1715 tomas.vondra              249 EUB             : 
 1715 tomas.vondra              250 GIC     9709854 :     return result;
 1715 tomas.vondra              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
 1715 tomas.vondra              262 GIC       31166 : float4_eq(const float4 val1, const float4 val2)
 1715 tomas.vondra              263 ECB             : {
 1715 tomas.vondra              264 GIC       31166 :     return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
 1715 tomas.vondra              265 ECB             : }
                                266                 : 
                                267                 : static inline bool
 1715 tomas.vondra              268 GIC     8464387 : float8_eq(const float8 val1, const float8 val2)
 1715 tomas.vondra              269 ECB             : {
 1715 tomas.vondra              270 GIC     8464387 :     return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
 1715 tomas.vondra              271 ECB             : }
                                272                 : 
                                273                 : static inline bool
 1715 tomas.vondra              274 GIC          15 : float4_ne(const float4 val1, const float4 val2)
 1715 tomas.vondra              275 ECB             : {
 1715 tomas.vondra              276 GIC          15 :     return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
 1715 tomas.vondra              277 ECB             : }
                                278                 : 
                                279                 : static inline bool
 1715 tomas.vondra              280 GIC        9912 : float8_ne(const float8 val1, const float8 val2)
 1715 tomas.vondra              281 ECB             : {
 1715 tomas.vondra              282 GIC        9912 :     return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
 1715 tomas.vondra              283 ECB             : }
                                284                 : 
                                285                 : static inline bool
 1715 tomas.vondra              286 GIC    24738422 : float4_lt(const float4 val1, const float4 val2)
 1715 tomas.vondra              287 ECB             : {
 1715 tomas.vondra              288 GIC    24738422 :     return !isnan(val1) && (isnan(val2) || val1 < val2);
 1715 tomas.vondra              289 ECB             : }
                                290                 : 
                                291                 : static inline bool
 1715 tomas.vondra              292 GIC    62399573 : float8_lt(const float8 val1, const float8 val2)
 1715 tomas.vondra              293 ECB             : {
 1715 tomas.vondra              294 GIC    62399573 :     return !isnan(val1) && (isnan(val2) || val1 < val2);
 1715 tomas.vondra              295 ECB             : }
                                296                 : 
                                297                 : static inline bool
 1715 tomas.vondra              298 GIC        1914 : float4_le(const float4 val1, const float4 val2)
 1715 tomas.vondra              299 ECB             : {
 1715 tomas.vondra              300 GIC        1914 :     return isnan(val2) || (!isnan(val1) && val1 <= val2);
 1715 tomas.vondra              301 ECB             : }
                                302                 : 
                                303                 : static inline bool
 1715 tomas.vondra              304 GIC    85143552 : float8_le(const float8 val1, const float8 val2)
 1715 tomas.vondra              305 ECB             : {
 1715 tomas.vondra              306 GIC    85143552 :     return isnan(val2) || (!isnan(val1) && val1 <= val2);
 1715 tomas.vondra              307 ECB             : }
                                308                 : 
                                309                 : static inline bool
 1715 tomas.vondra              310 GIC    25269094 : float4_gt(const float4 val1, const float4 val2)
 1715 tomas.vondra              311 ECB             : {
 1715 tomas.vondra              312 GIC    25269094 :     return !isnan(val2) && (isnan(val1) || val1 > val2);
 1715 tomas.vondra              313 ECB             : }
                                314                 : 
                                315                 : static inline bool
 1715 tomas.vondra              316 GIC    66649997 : float8_gt(const float8 val1, const float8 val2)
 1715 tomas.vondra              317 ECB             : {
 1715 tomas.vondra              318 GIC    66649997 :     return !isnan(val2) && (isnan(val1) || val1 > val2);
 1715 tomas.vondra              319 ECB             : }
                                320                 : 
                                321                 : static inline bool
 1715 tomas.vondra              322 GIC        1914 : float4_ge(const float4 val1, const float4 val2)
 1715 tomas.vondra              323 ECB             : {
 1715 tomas.vondra              324 GIC        1914 :     return isnan(val1) || (!isnan(val2) && val1 >= val2);
 1715 tomas.vondra              325 ECB             : }
                                326                 : 
                                327                 : static inline bool
 1715 tomas.vondra              328 GIC     4433507 : float8_ge(const float8 val1, const float8 val2)
 1715 tomas.vondra              329 ECB             : {
 1715 tomas.vondra              330 GIC     4433507 :     return isnan(val1) || (!isnan(val2) && val1 >= val2);
 1715 tomas.vondra              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
 1715 tomas.vondra              340 GIC    46795660 : float8_min(const float8 val1, const float8 val2)
 1715 tomas.vondra              341 ECB             : {
 1715 tomas.vondra              342 GIC    46795660 :     return float8_lt(val1, val2) ? val1 : val2;
 1715 tomas.vondra              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
 1715 tomas.vondra              352 GIC    46795660 : float8_max(const float8 val1, const float8 val2)
 1715 tomas.vondra              353 ECB             : {
 1715 tomas.vondra              354 GIC    46795660 :     return float8_gt(val1, val2) ? val1 : val2;
 1715 tomas.vondra              355 ECB             : }
                                356                 : 
                                357                 : #endif                          /* FLOAT_H */
        

Generated by: LCOV version v1.16-55-g56c0a2a