PostgreSQL Source Code git master
Loading...
Searching...
No Matches
float.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <float.h>
#include <math.h>
#include <limits.h>
#include "catalog/pg_type.h"
#include "common/int.h"
#include "common/shortest_dec.h"
#include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/fmgrprotos.h"
#include "utils/sortsupport.h"
Include dependency graph for float.c:

Go to the source code of this file.

Macros

#define INIT_DEGREE_CONSTANTS()
 

Functions

static double sind_q1 (double x)
 
static double cosd_q1 (double x)
 
static void init_degree_constants (void)
 
pg_noinline void float_overflow_error (void)
 
pg_noinline void float_underflow_error (void)
 
pg_noinline void float_zero_divide_error (void)
 
int is_infinite (double val)
 
Datum float4in (PG_FUNCTION_ARGS)
 
float4 float4in_internal (char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
 
Datum float4out (PG_FUNCTION_ARGS)
 
Datum float4recv (PG_FUNCTION_ARGS)
 
Datum float4send (PG_FUNCTION_ARGS)
 
Datum float8in (PG_FUNCTION_ARGS)
 
float8 float8in_internal (char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
 
Datum float8out (PG_FUNCTION_ARGS)
 
charfloat8out_internal (double num)
 
Datum float8recv (PG_FUNCTION_ARGS)
 
Datum float8send (PG_FUNCTION_ARGS)
 
Datum float4abs (PG_FUNCTION_ARGS)
 
Datum float4um (PG_FUNCTION_ARGS)
 
Datum float4up (PG_FUNCTION_ARGS)
 
Datum float4larger (PG_FUNCTION_ARGS)
 
Datum float4smaller (PG_FUNCTION_ARGS)
 
Datum float8abs (PG_FUNCTION_ARGS)
 
Datum float8um (PG_FUNCTION_ARGS)
 
Datum float8up (PG_FUNCTION_ARGS)
 
Datum float8larger (PG_FUNCTION_ARGS)
 
Datum float8smaller (PG_FUNCTION_ARGS)
 
Datum float4pl (PG_FUNCTION_ARGS)
 
Datum float4mi (PG_FUNCTION_ARGS)
 
Datum float4mul (PG_FUNCTION_ARGS)
 
Datum float4div (PG_FUNCTION_ARGS)
 
Datum float8pl (PG_FUNCTION_ARGS)
 
Datum float8mi (PG_FUNCTION_ARGS)
 
Datum float8mul (PG_FUNCTION_ARGS)
 
Datum float8div (PG_FUNCTION_ARGS)
 
int float4_cmp_internal (float4 a, float4 b)
 
Datum float4eq (PG_FUNCTION_ARGS)
 
Datum float4ne (PG_FUNCTION_ARGS)
 
Datum float4lt (PG_FUNCTION_ARGS)
 
Datum float4le (PG_FUNCTION_ARGS)
 
Datum float4gt (PG_FUNCTION_ARGS)
 
Datum float4ge (PG_FUNCTION_ARGS)
 
Datum btfloat4cmp (PG_FUNCTION_ARGS)
 
static int btfloat4fastcmp (Datum x, Datum y, SortSupport ssup)
 
Datum btfloat4sortsupport (PG_FUNCTION_ARGS)
 
int float8_cmp_internal (float8 a, float8 b)
 
Datum float8eq (PG_FUNCTION_ARGS)
 
Datum float8ne (PG_FUNCTION_ARGS)
 
Datum float8lt (PG_FUNCTION_ARGS)
 
Datum float8le (PG_FUNCTION_ARGS)
 
Datum float8gt (PG_FUNCTION_ARGS)
 
Datum float8ge (PG_FUNCTION_ARGS)
 
Datum btfloat8cmp (PG_FUNCTION_ARGS)
 
static int btfloat8fastcmp (Datum x, Datum y, SortSupport ssup)
 
Datum btfloat8sortsupport (PG_FUNCTION_ARGS)
 
Datum btfloat48cmp (PG_FUNCTION_ARGS)
 
Datum btfloat84cmp (PG_FUNCTION_ARGS)
 
Datum in_range_float8_float8 (PG_FUNCTION_ARGS)
 
Datum in_range_float4_float8 (PG_FUNCTION_ARGS)
 
Datum ftod (PG_FUNCTION_ARGS)
 
Datum dtof (PG_FUNCTION_ARGS)
 
Datum dtoi4 (PG_FUNCTION_ARGS)
 
Datum dtoi2 (PG_FUNCTION_ARGS)
 
Datum i4tod (PG_FUNCTION_ARGS)
 
Datum i2tod (PG_FUNCTION_ARGS)
 
Datum ftoi4 (PG_FUNCTION_ARGS)
 
Datum ftoi2 (PG_FUNCTION_ARGS)
 
Datum i4tof (PG_FUNCTION_ARGS)
 
Datum i2tof (PG_FUNCTION_ARGS)
 
Datum dround (PG_FUNCTION_ARGS)
 
Datum dceil (PG_FUNCTION_ARGS)
 
Datum dfloor (PG_FUNCTION_ARGS)
 
Datum dsign (PG_FUNCTION_ARGS)
 
Datum dtrunc (PG_FUNCTION_ARGS)
 
Datum dsqrt (PG_FUNCTION_ARGS)
 
Datum dcbrt (PG_FUNCTION_ARGS)
 
Datum dpow (PG_FUNCTION_ARGS)
 
Datum dexp (PG_FUNCTION_ARGS)
 
Datum dlog1 (PG_FUNCTION_ARGS)
 
Datum dlog10 (PG_FUNCTION_ARGS)
 
Datum dacos (PG_FUNCTION_ARGS)
 
Datum dasin (PG_FUNCTION_ARGS)
 
Datum datan (PG_FUNCTION_ARGS)
 
Datum datan2 (PG_FUNCTION_ARGS)
 
Datum dcos (PG_FUNCTION_ARGS)
 
Datum dcot (PG_FUNCTION_ARGS)
 
Datum dsin (PG_FUNCTION_ARGS)
 
Datum dtan (PG_FUNCTION_ARGS)
 
static double asind_q1 (double x)
 
static double acosd_q1 (double x)
 
Datum dacosd (PG_FUNCTION_ARGS)
 
Datum dasind (PG_FUNCTION_ARGS)
 
Datum datand (PG_FUNCTION_ARGS)
 
Datum datan2d (PG_FUNCTION_ARGS)
 
static double sind_0_to_30 (double x)
 
static double cosd_0_to_60 (double x)
 
Datum dcosd (PG_FUNCTION_ARGS)
 
Datum dcotd (PG_FUNCTION_ARGS)
 
Datum dsind (PG_FUNCTION_ARGS)
 
Datum dtand (PG_FUNCTION_ARGS)
 
Datum degrees (PG_FUNCTION_ARGS)
 
Datum dpi (PG_FUNCTION_ARGS)
 
Datum radians (PG_FUNCTION_ARGS)
 
Datum dsinh (PG_FUNCTION_ARGS)
 
Datum dcosh (PG_FUNCTION_ARGS)
 
Datum dtanh (PG_FUNCTION_ARGS)
 
Datum dasinh (PG_FUNCTION_ARGS)
 
Datum dacosh (PG_FUNCTION_ARGS)
 
Datum datanh (PG_FUNCTION_ARGS)
 
Datum derf (PG_FUNCTION_ARGS)
 
Datum derfc (PG_FUNCTION_ARGS)
 
Datum dgamma (PG_FUNCTION_ARGS)
 
Datum dlgamma (PG_FUNCTION_ARGS)
 
static float8check_float8_array (ArrayType *transarray, const char *caller, int n)
 
Datum float8_combine (PG_FUNCTION_ARGS)
 
Datum float8_accum (PG_FUNCTION_ARGS)
 
Datum float4_accum (PG_FUNCTION_ARGS)
 
Datum float8_avg (PG_FUNCTION_ARGS)
 
Datum float8_var_pop (PG_FUNCTION_ARGS)
 
Datum float8_var_samp (PG_FUNCTION_ARGS)
 
Datum float8_stddev_pop (PG_FUNCTION_ARGS)
 
Datum float8_stddev_samp (PG_FUNCTION_ARGS)
 
Datum float8_regr_accum (PG_FUNCTION_ARGS)
 
Datum float8_regr_combine (PG_FUNCTION_ARGS)
 
Datum float8_regr_sxx (PG_FUNCTION_ARGS)
 
Datum float8_regr_syy (PG_FUNCTION_ARGS)
 
Datum float8_regr_sxy (PG_FUNCTION_ARGS)
 
Datum float8_regr_avgx (PG_FUNCTION_ARGS)
 
Datum float8_regr_avgy (PG_FUNCTION_ARGS)
 
Datum float8_covar_pop (PG_FUNCTION_ARGS)
 
Datum float8_covar_samp (PG_FUNCTION_ARGS)
 
Datum float8_corr (PG_FUNCTION_ARGS)
 
Datum float8_regr_r2 (PG_FUNCTION_ARGS)
 
Datum float8_regr_slope (PG_FUNCTION_ARGS)
 
Datum float8_regr_intercept (PG_FUNCTION_ARGS)
 
Datum float48pl (PG_FUNCTION_ARGS)
 
Datum float48mi (PG_FUNCTION_ARGS)
 
Datum float48mul (PG_FUNCTION_ARGS)
 
Datum float48div (PG_FUNCTION_ARGS)
 
Datum float84pl (PG_FUNCTION_ARGS)
 
Datum float84mi (PG_FUNCTION_ARGS)
 
Datum float84mul (PG_FUNCTION_ARGS)
 
Datum float84div (PG_FUNCTION_ARGS)
 
Datum float48eq (PG_FUNCTION_ARGS)
 
Datum float48ne (PG_FUNCTION_ARGS)
 
Datum float48lt (PG_FUNCTION_ARGS)
 
Datum float48le (PG_FUNCTION_ARGS)
 
Datum float48gt (PG_FUNCTION_ARGS)
 
Datum float48ge (PG_FUNCTION_ARGS)
 
Datum float84eq (PG_FUNCTION_ARGS)
 
Datum float84ne (PG_FUNCTION_ARGS)
 
Datum float84lt (PG_FUNCTION_ARGS)
 
Datum float84le (PG_FUNCTION_ARGS)
 
Datum float84gt (PG_FUNCTION_ARGS)
 
Datum float84ge (PG_FUNCTION_ARGS)
 
Datum width_bucket_float8 (PG_FUNCTION_ARGS)
 

Variables

int extra_float_digits = 1
 
static bool degree_consts_set = false
 
static float8 sin_30 = 0
 
static float8 one_minus_cos_60 = 0
 
static float8 asin_0_5 = 0
 
static float8 acos_0_5 = 0
 
static float8 atan_1_0 = 0
 
static float8 tan_45 = 0
 
static float8 cot_45 = 0
 
float8 degree_c_thirty = 30.0
 
float8 degree_c_forty_five = 45.0
 
float8 degree_c_sixty = 60.0
 
float8 degree_c_one_half = 0.5
 
float8 degree_c_one = 1.0
 

Macro Definition Documentation

◆ INIT_DEGREE_CONSTANTS

#define INIT_DEGREE_CONSTANTS ( )
Value:
do { \
} while(0)
static bool degree_consts_set
Definition float.c:43
static int fb(int x)

Definition at line 2031 of file float.c.

2032 { \
2035} while(0)

Function Documentation

◆ acosd_q1()

static double acosd_q1 ( double  x)
static

Definition at line 2081 of file float.c.

2082{
2083 /*
2084 * Stitch together inverse sine and cosine functions for the ranges [0,
2085 * 0.5] and (0.5, 1]. Each expression below is guaranteed to return
2086 * exactly 60 for x=0.5, so the result is a continuous monotonic function
2087 * over the full range.
2088 */
2089 if (x <= 0.5)
2090 {
2091 volatile float8 asin_x = asin(x);
2092
2093 return 90.0 - (asin_x / asin_0_5) * 30.0;
2094 }
2095 else
2096 {
2097 volatile float8 acos_x = acos(x);
2098
2099 return (acos_x / acos_0_5) * 60.0;
2100 }
2101}
double float8
Definition c.h:656
static float8 acos_0_5
Definition float.c:47
static float8 asin_0_5
Definition float.c:46
int x
Definition isn.c:75

References acos_0_5, asin_0_5, fb(), and x.

Referenced by dacosd().

◆ asind_q1()

static double asind_q1 ( double  x)
static

Definition at line 2048 of file float.c.

2049{
2050 /*
2051 * Stitch together inverse sine and cosine functions for the ranges [0,
2052 * 0.5] and (0.5, 1]. Each expression below is guaranteed to return
2053 * exactly 30 for x=0.5, so the result is a continuous monotonic function
2054 * over the full range.
2055 */
2056 if (x <= 0.5)
2057 {
2058 volatile float8 asin_x = asin(x);
2059
2060 return (asin_x / asin_0_5) * 30.0;
2061 }
2062 else
2063 {
2064 volatile float8 acos_x = acos(x);
2065
2066 return 90.0 - (acos_x / acos_0_5) * 60.0;
2067 }
2068}

References acos_0_5, asin_0_5, fb(), and x.

Referenced by dacosd(), and dasind().

◆ btfloat48cmp()

Datum btfloat48cmp ( PG_FUNCTION_ARGS  )

Definition at line 1001 of file float.c.

1002{
1005
1006 /* widen float4 to float8 and then compare */
1008}
float float4
Definition c.h:655
int float8_cmp_internal(float8 a, float8 b)
Definition float.c:910
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_GETARG_FLOAT4(n)
Definition fmgr.h:282

References fb(), float8_cmp_internal(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_INT32.

◆ btfloat4cmp()

Datum btfloat4cmp ( PG_FUNCTION_ARGS  )

Definition at line 880 of file float.c.

881{
884
886}
int float4_cmp_internal(float4 a, float4 b)
Definition float.c:816

References fb(), float4_cmp_internal(), PG_GETARG_FLOAT4, and PG_RETURN_INT32.

◆ btfloat4fastcmp()

static int btfloat4fastcmp ( Datum  x,
Datum  y,
SortSupport  ssup 
)
static

Definition at line 889 of file float.c.

890{
893
895}
int y
Definition isn.c:76
static float4 DatumGetFloat4(Datum X)
Definition postgres.h:461

References DatumGetFloat4(), fb(), float4_cmp_internal(), x, and y.

Referenced by btfloat4sortsupport().

◆ btfloat4sortsupport()

Datum btfloat4sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 898 of file float.c.

899{
901
904}
static int btfloat4fastcmp(Datum x, Datum y, SortSupport ssup)
Definition float.c:889
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
struct SortSupportData * SortSupport
Definition sortsupport.h:58
int(* comparator)(Datum x, Datum y, SortSupport ssup)

References btfloat4fastcmp(), SortSupportData::comparator, PG_GETARG_POINTER, and PG_RETURN_VOID.

◆ btfloat84cmp()

Datum btfloat84cmp ( PG_FUNCTION_ARGS  )

Definition at line 1011 of file float.c.

1012{
1015
1016 /* widen float4 to float8 and then compare */
1018}

References fb(), float8_cmp_internal(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_INT32.

◆ btfloat8cmp()

Datum btfloat8cmp ( PG_FUNCTION_ARGS  )

◆ btfloat8fastcmp()

static int btfloat8fastcmp ( Datum  x,
Datum  y,
SortSupport  ssup 
)
static

Definition at line 983 of file float.c.

984{
987
989}
static float8 DatumGetFloat8(Datum X)
Definition postgres.h:495

References DatumGetFloat8(), fb(), float8_cmp_internal(), x, and y.

Referenced by btfloat8sortsupport().

◆ btfloat8sortsupport()

Datum btfloat8sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 992 of file float.c.

993{
995
998}
static int btfloat8fastcmp(Datum x, Datum y, SortSupport ssup)
Definition float.c:983

References btfloat8fastcmp(), SortSupportData::comparator, PG_GETARG_POINTER, and PG_RETURN_VOID.

◆ check_float8_array()

static float8 * check_float8_array ( ArrayType transarray,
const char caller,
int  n 
)
static

Definition at line 2933 of file float.c.

2934{
2935 /*
2936 * We expect the input to be an N-element float array; verify that. We
2937 * don't need to use deconstruct_array() since the array data is just
2938 * going to look like a C array of N float8 values.
2939 */
2940 if (ARR_NDIM(transarray) != 1 ||
2941 ARR_DIMS(transarray)[0] != n ||
2944 elog(ERROR, "%s: expected %d-element float8 array", caller, n);
2945 return (float8 *) ARR_DATA_PTR(transarray);
2946}
#define ARR_NDIM(a)
Definition array.h:290
#define ARR_DATA_PTR(a)
Definition array.h:322
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_DIMS(a)
Definition array.h:294
#define ARR_HASNULL(a)
Definition array.h:291
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, elog, ERROR, and fb().

Referenced by float4_accum(), float8_accum(), float8_avg(), float8_combine(), float8_corr(), float8_covar_pop(), float8_covar_samp(), float8_regr_accum(), float8_regr_avgx(), float8_regr_avgy(), float8_regr_combine(), float8_regr_intercept(), float8_regr_r2(), float8_regr_slope(), float8_regr_sxx(), float8_regr_sxy(), float8_regr_syy(), float8_stddev_pop(), float8_stddev_samp(), float8_var_pop(), and float8_var_samp().

◆ cosd_0_to_60()

static double cosd_0_to_60 ( double  x)
static

Definition at line 2266 of file float.c.

2267{
2268 volatile float8 one_minus_cos_x = 1.0 - cos(x * RADIANS_PER_DEGREE);
2269
2270 return 1.0 - (one_minus_cos_x / one_minus_cos_60) / 2.0;
2271}
static float8 one_minus_cos_60
Definition float.c:45
#define RADIANS_PER_DEGREE
Definition float.h:26

References fb(), one_minus_cos_60, RADIANS_PER_DEGREE, and x.

Referenced by cosd_q1(), and sind_q1().

◆ cosd_q1()

static double cosd_q1 ( double  x)
static

Definition at line 2299 of file float.c.

2300{
2301 /*
2302 * Stitch together the sine and cosine functions for the ranges [0, 60]
2303 * and (60, 90]. These guarantee to return exact answers at their
2304 * endpoints, so the overall result is a continuous monotonic function
2305 * that gives exact results when x = 0, 60 and 90 degrees.
2306 */
2307 if (x <= 60.0)
2308 return cosd_0_to_60(x);
2309 else
2310 return sind_0_to_30(90.0 - x);
2311}
static double sind_0_to_30(double x)
Definition float.c:2252
static double cosd_0_to_60(double x)
Definition float.c:2266

References cosd_0_to_60(), sind_0_to_30(), and x.

Referenced by dcosd(), dcotd(), dtand(), and init_degree_constants().

◆ dacos()

Datum dacos ( PG_FUNCTION_ARGS  )

Definition at line 1755 of file float.c.

1756{
1758 float8 result;
1759
1760 /* Per the POSIX spec, return NaN if the input is NaN */
1761 if (isnan(arg1))
1763
1764 /*
1765 * The principal branch of the inverse cosine function maps values in the
1766 * range [-1, 1] to values in the range [0, Pi], so we should reject any
1767 * inputs outside that range and the result will always be finite.
1768 */
1769 if (arg1 < -1.0 || arg1 > 1.0)
1770 ereport(ERROR,
1772 errmsg("input is out of range")));
1773
1774 result = acos(arg1);
1775 if (unlikely(isinf(result)))
1777
1778 PG_RETURN_FLOAT8(result);
1779}
#define unlikely(x)
Definition c.h:424
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
#define ereport(elevel,...)
Definition elog.h:150
pg_noinline void float_overflow_error(void)
Definition float.c:86
static float8 get_float8_nan(void)
Definition float.h:84
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), get_float8_nan(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dacosd()

Datum dacosd ( PG_FUNCTION_ARGS  )

Definition at line 2108 of file float.c.

2109{
2111 float8 result;
2112
2113 /* Per the POSIX spec, return NaN if the input is NaN */
2114 if (isnan(arg1))
2116
2118
2119 /*
2120 * The principal branch of the inverse cosine function maps values in the
2121 * range [-1, 1] to values in the range [0, 180], so we should reject any
2122 * inputs outside that range and the result will always be finite.
2123 */
2124 if (arg1 < -1.0 || arg1 > 1.0)
2125 ereport(ERROR,
2127 errmsg("input is out of range")));
2128
2129 if (arg1 >= 0.0)
2130 result = acosd_q1(arg1);
2131 else
2132 result = 90.0 + asind_q1(-arg1);
2133
2134 if (unlikely(isinf(result)))
2136
2137 PG_RETURN_FLOAT8(result);
2138}
static double acosd_q1(double x)
Definition float.c:2081
static double asind_q1(double x)
Definition float.c:2048
#define INIT_DEGREE_CONSTANTS()
Definition float.c:2031

References acosd_q1(), asind_q1(), ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), get_float8_nan(), INIT_DEGREE_CONSTANTS, PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dacosh()

Datum dacosh ( PG_FUNCTION_ARGS  )

Definition at line 2689 of file float.c.

2690{
2692 float8 result;
2693
2694 /*
2695 * acosh is only defined for inputs >= 1.0. By checking this ourselves,
2696 * we need not worry about checking for an EDOM error, which is a good
2697 * thing because some implementations will report that for NaN. Otherwise,
2698 * no error is possible.
2699 */
2700 if (arg1 < 1.0)
2701 ereport(ERROR,
2703 errmsg("input is out of range")));
2704
2705 result = acosh(arg1);
2706
2707 PG_RETURN_FLOAT8(result);
2708}

References ereport, errcode(), errmsg(), ERROR, fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dasin()

Datum dasin ( PG_FUNCTION_ARGS  )

Definition at line 1786 of file float.c.

1787{
1789 float8 result;
1790
1791 /* Per the POSIX spec, return NaN if the input is NaN */
1792 if (isnan(arg1))
1794
1795 /*
1796 * The principal branch of the inverse sine function maps values in the
1797 * range [-1, 1] to values in the range [-Pi/2, Pi/2], so we should reject
1798 * any inputs outside that range and the result will always be finite.
1799 */
1800 if (arg1 < -1.0 || arg1 > 1.0)
1801 ereport(ERROR,
1803 errmsg("input is out of range")));
1804
1805 result = asin(arg1);
1806 if (unlikely(isinf(result)))
1808
1809 PG_RETURN_FLOAT8(result);
1810}

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), get_float8_nan(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dasind()

Datum dasind ( PG_FUNCTION_ARGS  )

Definition at line 2145 of file float.c.

2146{
2148 float8 result;
2149
2150 /* Per the POSIX spec, return NaN if the input is NaN */
2151 if (isnan(arg1))
2153
2155
2156 /*
2157 * The principal branch of the inverse sine function maps values in the
2158 * range [-1, 1] to values in the range [-90, 90], so we should reject any
2159 * inputs outside that range and the result will always be finite.
2160 */
2161 if (arg1 < -1.0 || arg1 > 1.0)
2162 ereport(ERROR,
2164 errmsg("input is out of range")));
2165
2166 if (arg1 >= 0.0)
2167 result = asind_q1(arg1);
2168 else
2169 result = -asind_q1(-arg1);
2170
2171 if (unlikely(isinf(result)))
2173
2174 PG_RETURN_FLOAT8(result);
2175}

References asind_q1(), ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), get_float8_nan(), INIT_DEGREE_CONSTANTS, PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dasinh()

Datum dasinh ( PG_FUNCTION_ARGS  )

Definition at line 2672 of file float.c.

2673{
2675 float8 result;
2676
2677 /*
2678 * For asinh, we don't need an errno check because it never overflows.
2679 */
2680 result = asinh(arg1);
2681
2682 PG_RETURN_FLOAT8(result);
2683}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ datan()

Datum datan ( PG_FUNCTION_ARGS  )

Definition at line 1817 of file float.c.

1818{
1820 float8 result;
1821
1822 /* Per the POSIX spec, return NaN if the input is NaN */
1823 if (isnan(arg1))
1825
1826 /*
1827 * The principal branch of the inverse tangent function maps all inputs to
1828 * values in the range [-Pi/2, Pi/2], so the result should always be
1829 * finite, even if the input is infinite.
1830 */
1831 result = atan(arg1);
1832 if (unlikely(isinf(result)))
1834
1835 PG_RETURN_FLOAT8(result);
1836}

References fb(), float_overflow_error(), get_float8_nan(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ datan2()

Datum datan2 ( PG_FUNCTION_ARGS  )

Definition at line 1843 of file float.c.

1844{
1847 float8 result;
1848
1849 /* Per the POSIX spec, return NaN if either input is NaN */
1850 if (isnan(arg1) || isnan(arg2))
1852
1853 /*
1854 * atan2 maps all inputs to values in the range [-Pi, Pi], so the result
1855 * should always be finite, even if the inputs are infinite.
1856 */
1857 result = atan2(arg1, arg2);
1858 if (unlikely(isinf(result)))
1860
1861 PG_RETURN_FLOAT8(result);
1862}

References fb(), float_overflow_error(), get_float8_nan(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ datan2d()

Datum datan2d ( PG_FUNCTION_ARGS  )

Definition at line 2214 of file float.c.

2215{
2218 float8 result;
2219 volatile float8 atan2_arg1_arg2;
2220
2221 /* Per the POSIX spec, return NaN if either input is NaN */
2222 if (isnan(arg1) || isnan(arg2))
2224
2226
2227 /*
2228 * atan2d maps all inputs to values in the range [-180, 180], so the
2229 * result should always be finite, even if the inputs are infinite.
2230 *
2231 * Note: this coding assumes that atan(1.0) is a suitable scaling constant
2232 * to get an exact result from atan2(). This might well fail on us at
2233 * some point, requiring us to decide exactly what inputs we think we're
2234 * going to guarantee an exact result for.
2235 */
2237 result = (atan2_arg1_arg2 / atan_1_0) * 45.0;
2238
2239 if (unlikely(isinf(result)))
2241
2242 PG_RETURN_FLOAT8(result);
2243}
static float8 atan_1_0
Definition float.c:48

References atan_1_0, fb(), float_overflow_error(), get_float8_nan(), INIT_DEGREE_CONSTANTS, PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ datand()

Datum datand ( PG_FUNCTION_ARGS  )

Definition at line 2182 of file float.c.

2183{
2185 float8 result;
2186 volatile float8 atan_arg1;
2187
2188 /* Per the POSIX spec, return NaN if the input is NaN */
2189 if (isnan(arg1))
2191
2193
2194 /*
2195 * The principal branch of the inverse tangent function maps all inputs to
2196 * values in the range [-90, 90], so the result should always be finite,
2197 * even if the input is infinite. Additionally, we take care to ensure
2198 * than when arg1 is 1, the result is exactly 45.
2199 */
2200 atan_arg1 = atan(arg1);
2201 result = (atan_arg1 / atan_1_0) * 45.0;
2202
2203 if (unlikely(isinf(result)))
2205
2206 PG_RETURN_FLOAT8(result);
2207}

References atan_1_0, fb(), float_overflow_error(), get_float8_nan(), INIT_DEGREE_CONSTANTS, PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ datanh()

Datum datanh ( PG_FUNCTION_ARGS  )

Definition at line 2714 of file float.c.

2715{
2717 float8 result;
2718
2719 /*
2720 * atanh is only defined for inputs between -1 and 1. By checking this
2721 * ourselves, we need not worry about checking for an EDOM error, which is
2722 * a good thing because some implementations will report that for NaN.
2723 */
2724 if (arg1 < -1.0 || arg1 > 1.0)
2725 ereport(ERROR,
2727 errmsg("input is out of range")));
2728
2729 /*
2730 * Also handle the infinity cases ourselves; this is helpful because old
2731 * glibc versions may produce the wrong errno for this. All other inputs
2732 * cannot produce an error.
2733 */
2734 if (arg1 == -1.0)
2735 result = -get_float8_infinity();
2736 else if (arg1 == 1.0)
2737 result = get_float8_infinity();
2738 else
2739 result = atanh(arg1);
2740
2741 PG_RETURN_FLOAT8(result);
2742}
static float8 get_float8_infinity(void)
Definition float.h:65

References ereport, errcode(), errmsg(), ERROR, fb(), get_float8_infinity(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dcbrt()

Datum dcbrt ( PG_FUNCTION_ARGS  )

Definition at line 1470 of file float.c.

1471{
1473 float8 result;
1474
1475 result = cbrt(arg1);
1476 if (unlikely(isinf(result)) && !isinf(arg1))
1478 if (unlikely(result == 0.0) && arg1 != 0.0)
1480
1481 PG_RETURN_FLOAT8(result);
1482}
pg_noinline void float_underflow_error(void)
Definition float.c:94

References fb(), float_overflow_error(), float_underflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dceil()

Datum dceil ( PG_FUNCTION_ARGS  )

Definition at line 1380 of file float.c.

1381{
1383
1385}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dcos()

Datum dcos ( PG_FUNCTION_ARGS  )

Definition at line 1869 of file float.c.

1870{
1872 float8 result;
1873
1874 /* Per the POSIX spec, return NaN if the input is NaN */
1875 if (isnan(arg1))
1877
1878 /*
1879 * cos() is periodic and so theoretically can work for all finite inputs,
1880 * but some implementations may choose to throw error if the input is so
1881 * large that there are no significant digits in the result. So we should
1882 * check for errors. POSIX allows an error to be reported either via
1883 * errno or via fetestexcept(), but currently we only support checking
1884 * errno. (fetestexcept() is rumored to report underflow unreasonably
1885 * early on some platforms, so it's not clear that believing it would be a
1886 * net improvement anyway.)
1887 *
1888 * For infinite inputs, POSIX specifies that the trigonometric functions
1889 * should return a domain error; but we won't notice that unless the
1890 * platform reports via errno, so also explicitly test for infinite
1891 * inputs.
1892 */
1893 errno = 0;
1894 result = cos(arg1);
1895 if (errno != 0 || isinf(arg1))
1896 ereport(ERROR,
1898 errmsg("input is out of range")));
1899 if (unlikely(isinf(result)))
1901
1902 PG_RETURN_FLOAT8(result);
1903}

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), get_float8_nan(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dcosd()

Datum dcosd ( PG_FUNCTION_ARGS  )

Definition at line 2318 of file float.c.

2319{
2321 float8 result;
2322 int sign = 1;
2323
2324 /*
2325 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2326 * if the input is infinite.
2327 */
2328 if (isnan(arg1))
2330
2331 if (isinf(arg1))
2332 ereport(ERROR,
2334 errmsg("input is out of range")));
2335
2337
2338 /* Reduce the range of the input to [0,90] degrees */
2339 arg1 = fmod(arg1, 360.0);
2340
2341 if (arg1 < 0.0)
2342 {
2343 /* cosd(-x) = cosd(x) */
2344 arg1 = -arg1;
2345 }
2346
2347 if (arg1 > 180.0)
2348 {
2349 /* cosd(360-x) = cosd(x) */
2350 arg1 = 360.0 - arg1;
2351 }
2352
2353 if (arg1 > 90.0)
2354 {
2355 /* cosd(180-x) = -cosd(x) */
2356 arg1 = 180.0 - arg1;
2357 sign = -sign;
2358 }
2359
2360 result = sign * cosd_q1(arg1);
2361
2362 if (unlikely(isinf(result)))
2364
2365 PG_RETURN_FLOAT8(result);
2366}
static double cosd_q1(double x)
Definition float.c:2299
char sign
Definition informix.c:693

References cosd_q1(), ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), get_float8_nan(), INIT_DEGREE_CONSTANTS, PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, sign, and unlikely.

◆ dcosh()

Datum dcosh ( PG_FUNCTION_ARGS  )

Definition at line 2627 of file float.c.

2628{
2630 float8 result;
2631
2632 errno = 0;
2633 result = cosh(arg1);
2634
2635 /*
2636 * if an ERANGE error occurs, it means there is an overflow. As cosh is
2637 * always positive, it always means the result is positive infinity.
2638 */
2639 if (errno == ERANGE)
2640 result = get_float8_infinity();
2641
2642 if (unlikely(result == 0.0))
2644
2645 PG_RETURN_FLOAT8(result);
2646}

References fb(), float_underflow_error(), get_float8_infinity(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dcot()

Datum dcot ( PG_FUNCTION_ARGS  )

Definition at line 1910 of file float.c.

1911{
1913 float8 result;
1914
1915 /* Per the POSIX spec, return NaN if the input is NaN */
1916 if (isnan(arg1))
1918
1919 /* Be sure to throw an error if the input is infinite --- see dcos() */
1920 errno = 0;
1921 result = tan(arg1);
1922 if (errno != 0 || isinf(arg1))
1923 ereport(ERROR,
1925 errmsg("input is out of range")));
1926
1927 result = 1.0 / result;
1928 /* Not checking for overflow because cot(0) == Inf */
1929
1930 PG_RETURN_FLOAT8(result);
1931}

References ereport, errcode(), errmsg(), ERROR, fb(), get_float8_nan(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dcotd()

Datum dcotd ( PG_FUNCTION_ARGS  )

Definition at line 2373 of file float.c.

2374{
2376 float8 result;
2377 volatile float8 cot_arg1;
2378 int sign = 1;
2379
2380 /*
2381 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2382 * if the input is infinite.
2383 */
2384 if (isnan(arg1))
2386
2387 if (isinf(arg1))
2388 ereport(ERROR,
2390 errmsg("input is out of range")));
2391
2393
2394 /* Reduce the range of the input to [0,90] degrees */
2395 arg1 = fmod(arg1, 360.0);
2396
2397 if (arg1 < 0.0)
2398 {
2399 /* cotd(-x) = -cotd(x) */
2400 arg1 = -arg1;
2401 sign = -sign;
2402 }
2403
2404 if (arg1 > 180.0)
2405 {
2406 /* cotd(360-x) = -cotd(x) */
2407 arg1 = 360.0 - arg1;
2408 sign = -sign;
2409 }
2410
2411 if (arg1 > 90.0)
2412 {
2413 /* cotd(180-x) = -cotd(x) */
2414 arg1 = 180.0 - arg1;
2415 sign = -sign;
2416 }
2417
2419 result = sign * (cot_arg1 / cot_45);
2420
2421 /*
2422 * On some machines we get cotd(270) = minus zero, but this isn't always
2423 * true. For portability, and because the user constituency for this
2424 * function probably doesn't want minus zero, force it to plain zero.
2425 */
2426 if (result == 0.0)
2427 result = 0.0;
2428
2429 /* Not checking for overflow because cotd(0) == Inf */
2430
2431 PG_RETURN_FLOAT8(result);
2432}
static float8 cot_45
Definition float.c:50
static double sind_q1(double x)
Definition float.c:2279

References cosd_q1(), cot_45, ereport, errcode(), errmsg(), ERROR, fb(), get_float8_nan(), INIT_DEGREE_CONSTANTS, PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, sign, and sind_q1().

◆ degrees()

Datum degrees ( PG_FUNCTION_ARGS  )

Definition at line 2561 of file float.c.

2562{
2564
2566}
static float8 float8_div(const float8 val1, const float8 val2)
Definition float.h:193

References fb(), float8_div(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and RADIANS_PER_DEGREE.

Referenced by degtorad().

◆ derf()

Datum derf ( PG_FUNCTION_ARGS  )

Definition at line 2752 of file float.c.

2753{
2755 float8 result;
2756
2757 /*
2758 * For erf, we don't need an errno check because it never overflows.
2759 */
2760 result = erf(arg1);
2761
2762 if (unlikely(isinf(result)))
2764
2765 PG_RETURN_FLOAT8(result);
2766}

References fb(), float_overflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ derfc()

Datum derfc ( PG_FUNCTION_ARGS  )

Definition at line 2772 of file float.c.

2773{
2775 float8 result;
2776
2777 /*
2778 * For erfc, we don't need an errno check because it never overflows.
2779 */
2780 result = erfc(arg1);
2781
2782 if (unlikely(isinf(result)))
2784
2785 PG_RETURN_FLOAT8(result);
2786}

References fb(), float_overflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dexp()

Datum dexp ( PG_FUNCTION_ARGS  )

Definition at line 1644 of file float.c.

1645{
1647 float8 result;
1648
1649 /*
1650 * Handle NaN and Inf cases explicitly. This avoids needing to assume
1651 * that the platform's exp() conforms to POSIX for these cases, and it
1652 * removes some edge cases for the overflow checks below.
1653 */
1654 if (isnan(arg1))
1655 result = arg1;
1656 else if (isinf(arg1))
1657 {
1658 /* Per POSIX, exp(-Inf) is 0 */
1659 result = (arg1 > 0.0) ? arg1 : 0;
1660 }
1661 else
1662 {
1663 /*
1664 * On some platforms, exp() will not set errno but just return Inf or
1665 * zero to report overflow/underflow; therefore, test both cases.
1666 */
1667 errno = 0;
1668 result = exp(arg1);
1669 if (unlikely(errno == ERANGE))
1670 {
1671 if (result != 0.0)
1673 else
1675 }
1676 else if (unlikely(isinf(result)))
1678 else if (unlikely(result == 0.0))
1680 }
1681
1682 PG_RETURN_FLOAT8(result);
1683}

References fb(), float_overflow_error(), float_underflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dfloor()

Datum dfloor ( PG_FUNCTION_ARGS  )

Definition at line 1392 of file float.c.

1393{
1395
1397}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dgamma()

Datum dgamma ( PG_FUNCTION_ARGS  )

Definition at line 2796 of file float.c.

2797{
2799 float8 result;
2800
2801 /*
2802 * Handle NaN and Inf cases explicitly. This simplifies the overflow
2803 * checks on platforms that do not set errno.
2804 */
2805 if (isnan(arg1))
2806 result = arg1;
2807 else if (isinf(arg1))
2808 {
2809 /* Per POSIX, an input of -Inf causes a domain error */
2810 if (arg1 < 0)
2811 {
2813 result = get_float8_nan(); /* keep compiler quiet */
2814 }
2815 else
2816 result = arg1;
2817 }
2818 else
2819 {
2820 /*
2821 * Note: the POSIX/C99 gamma function is called "tgamma", not "gamma".
2822 *
2823 * On some platforms, tgamma() will not set errno but just return Inf,
2824 * NaN, or zero to report overflow/underflow; therefore, test those
2825 * cases explicitly (note that, like the exponential function, the
2826 * gamma function has no zeros).
2827 */
2828 errno = 0;
2829 result = tgamma(arg1);
2830
2831 if (errno != 0 || isinf(result) || isnan(result))
2832 {
2833 if (result != 0.0)
2835 else
2837 }
2838 else if (result == 0.0)
2840 }
2841
2842 PG_RETURN_FLOAT8(result);
2843}

References fb(), float_overflow_error(), float_underflow_error(), get_float8_nan(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dlgamma()

Datum dlgamma ( PG_FUNCTION_ARGS  )

Definition at line 2850 of file float.c.

2851{
2853 float8 result;
2854
2855 /* On some versions of AIX, lgamma(NaN) fails with ERANGE */
2856#if defined(_AIX)
2857 if (isnan(arg1))
2859#endif
2860
2861 /*
2862 * Note: lgamma may not be thread-safe because it may write to a global
2863 * variable signgam, which may not be thread-local. However, this doesn't
2864 * matter to us, since we don't use signgam.
2865 */
2866 errno = 0;
2867 result = lgamma(arg1);
2868
2869 /*
2870 * If an ERANGE error occurs, it means there was an overflow or a pole
2871 * error (which happens for zero and negative integer inputs).
2872 *
2873 * On some platforms, lgamma() will not set errno but just return infinity
2874 * to report overflow, but it should never underflow.
2875 */
2876 if (errno == ERANGE || (isinf(result) && !isinf(arg1)))
2878
2879 PG_RETURN_FLOAT8(result);
2880}

References fb(), float_overflow_error(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dlog1()

Datum dlog1 ( PG_FUNCTION_ARGS  )

Definition at line 1690 of file float.c.

1691{
1693 float8 result;
1694
1695 /*
1696 * Emit particular SQLSTATE error codes for ln(). This is required by the
1697 * SQL standard.
1698 */
1699 if (arg1 == 0.0)
1700 ereport(ERROR,
1702 errmsg("cannot take logarithm of zero")));
1703 if (arg1 < 0)
1704 ereport(ERROR,
1706 errmsg("cannot take logarithm of a negative number")));
1707
1708 result = log(arg1);
1709 if (unlikely(isinf(result)) && !isinf(arg1))
1711 if (unlikely(result == 0.0) && arg1 != 1.0)
1713
1714 PG_RETURN_FLOAT8(result);
1715}

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), float_underflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dlog10()

Datum dlog10 ( PG_FUNCTION_ARGS  )

Definition at line 1722 of file float.c.

1723{
1725 float8 result;
1726
1727 /*
1728 * Emit particular SQLSTATE error codes for log(). The SQL spec doesn't
1729 * define log(), but it does define ln(), so it makes sense to emit the
1730 * same error code for an analogous error condition.
1731 */
1732 if (arg1 == 0.0)
1733 ereport(ERROR,
1735 errmsg("cannot take logarithm of zero")));
1736 if (arg1 < 0)
1737 ereport(ERROR,
1739 errmsg("cannot take logarithm of a negative number")));
1740
1741 result = log10(arg1);
1742 if (unlikely(isinf(result)) && !isinf(arg1))
1744 if (unlikely(result == 0.0) && arg1 != 1.0)
1746
1747 PG_RETURN_FLOAT8(result);
1748}

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), float_underflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dpi()

Definition at line 2573 of file float.c.

2574{
2576}
#define M_PI

References M_PI, and PG_RETURN_FLOAT8.

◆ dpow()

Datum dpow ( PG_FUNCTION_ARGS  )

Definition at line 1489 of file float.c.

1490{
1493 float8 result;
1494
1495 /*
1496 * The POSIX spec says that NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other
1497 * cases with NaN inputs yield NaN (with no error). Many older platforms
1498 * get one or more of these cases wrong, so deal with them via explicit
1499 * logic rather than trusting pow(3).
1500 */
1501 if (isnan(arg1))
1502 {
1503 if (isnan(arg2) || arg2 != 0.0)
1505 PG_RETURN_FLOAT8(1.0);
1506 }
1507 if (isnan(arg2))
1508 {
1509 if (arg1 != 1.0)
1511 PG_RETURN_FLOAT8(1.0);
1512 }
1513
1514 /*
1515 * The SQL spec requires that we emit a particular SQLSTATE error code for
1516 * certain error conditions. Specifically, we don't return a
1517 * divide-by-zero error code for 0 ^ -1.
1518 */
1519 if (arg1 == 0 && arg2 < 0)
1520 ereport(ERROR,
1522 errmsg("zero raised to a negative power is undefined")));
1523 if (arg1 < 0 && floor(arg2) != arg2)
1524 ereport(ERROR,
1526 errmsg("a negative number raised to a non-integer power yields a complex result")));
1527
1528 /*
1529 * We don't trust the platform's pow() to handle infinity cases per POSIX
1530 * spec either, so deal with those explicitly too. It's easier to handle
1531 * infinite y first, so that it doesn't matter if x is also infinite.
1532 */
1533 if (isinf(arg2))
1534 {
1535 float8 absx = fabs(arg1);
1536
1537 if (absx == 1.0)
1538 result = 1.0;
1539 else if (arg2 > 0.0) /* y = +Inf */
1540 {
1541 if (absx > 1.0)
1542 result = arg2;
1543 else
1544 result = 0.0;
1545 }
1546 else /* y = -Inf */
1547 {
1548 if (absx > 1.0)
1549 result = 0.0;
1550 else
1551 result = -arg2;
1552 }
1553 }
1554 else if (isinf(arg1))
1555 {
1556 if (arg2 == 0.0)
1557 result = 1.0;
1558 else if (arg1 > 0.0) /* x = +Inf */
1559 {
1560 if (arg2 > 0.0)
1561 result = arg1;
1562 else
1563 result = 0.0;
1564 }
1565 else /* x = -Inf */
1566 {
1567 /*
1568 * Per POSIX, the sign of the result depends on whether y is an
1569 * odd integer. Since x < 0, we already know from the previous
1570 * domain check that y is an integer. It is odd if y/2 is not
1571 * also an integer.
1572 */
1573 float8 halfy = arg2 / 2; /* should be computed exactly */
1574 bool yisoddinteger = (floor(halfy) != halfy);
1575
1576 if (arg2 > 0.0)
1577 result = yisoddinteger ? arg1 : -arg1;
1578 else
1579 result = yisoddinteger ? -0.0 : 0.0;
1580 }
1581 }
1582 else
1583 {
1584 /*
1585 * pow() sets errno on only some platforms, depending on whether it
1586 * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we must check both
1587 * errno and invalid output values. (We can't rely on just the
1588 * latter, either; some old platforms return a large-but-finite
1589 * HUGE_VAL when reporting overflow.)
1590 */
1591 errno = 0;
1592 result = pow(arg1, arg2);
1593 if (errno == EDOM || isnan(result))
1594 {
1595 /*
1596 * We handled all possible domain errors above, so this should be
1597 * impossible. However, old glibc versions on x86 have a bug that
1598 * causes them to fail this way for abs(y) greater than 2^63:
1599 *
1600 * https://sourceware.org/bugzilla/show_bug.cgi?id=3866
1601 *
1602 * Hence, if we get here, assume y is finite but large (large
1603 * enough to be certainly even). The result should be 0 if x == 0,
1604 * 1.0 if abs(x) == 1.0, otherwise an overflow or underflow error.
1605 */
1606 if (arg1 == 0.0)
1607 result = 0.0; /* we already verified y is positive */
1608 else
1609 {
1610 float8 absx = fabs(arg1);
1611
1612 if (absx == 1.0)
1613 result = 1.0;
1614 else if (arg2 >= 0.0 ? (absx > 1.0) : (absx < 1.0))
1616 else
1618 }
1619 }
1620 else if (errno == ERANGE)
1621 {
1622 if (result != 0.0)
1624 else
1626 }
1627 else
1628 {
1629 if (unlikely(isinf(result)))
1631 if (unlikely(result == 0.0) && arg1 != 0.0)
1633 }
1634 }
1635
1636 PG_RETURN_FLOAT8(result);
1637}

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), float_underflow_error(), get_float8_nan(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dround()

Datum dround ( PG_FUNCTION_ARGS  )

Definition at line 1368 of file float.c.

1369{
1371
1373}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsign()

Datum dsign ( PG_FUNCTION_ARGS  )

Definition at line 1405 of file float.c.

1406{
1408 float8 result;
1409
1410 if (arg1 > 0)
1411 result = 1.0;
1412 else if (arg1 < 0)
1413 result = -1.0;
1414 else
1415 result = 0.0;
1416
1417 PG_RETURN_FLOAT8(result);
1418}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsin()

Datum dsin ( PG_FUNCTION_ARGS  )

Definition at line 1938 of file float.c.

1939{
1941 float8 result;
1942
1943 /* Per the POSIX spec, return NaN if the input is NaN */
1944 if (isnan(arg1))
1946
1947 /* Be sure to throw an error if the input is infinite --- see dcos() */
1948 errno = 0;
1949 result = sin(arg1);
1950 if (errno != 0 || isinf(arg1))
1951 ereport(ERROR,
1953 errmsg("input is out of range")));
1954 if (unlikely(isinf(result)))
1956
1957 PG_RETURN_FLOAT8(result);
1958}

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), get_float8_nan(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dsind()

Datum dsind ( PG_FUNCTION_ARGS  )

Definition at line 2439 of file float.c.

2440{
2442 float8 result;
2443 int sign = 1;
2444
2445 /*
2446 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2447 * if the input is infinite.
2448 */
2449 if (isnan(arg1))
2451
2452 if (isinf(arg1))
2453 ereport(ERROR,
2455 errmsg("input is out of range")));
2456
2458
2459 /* Reduce the range of the input to [0,90] degrees */
2460 arg1 = fmod(arg1, 360.0);
2461
2462 if (arg1 < 0.0)
2463 {
2464 /* sind(-x) = -sind(x) */
2465 arg1 = -arg1;
2466 sign = -sign;
2467 }
2468
2469 if (arg1 > 180.0)
2470 {
2471 /* sind(360-x) = -sind(x) */
2472 arg1 = 360.0 - arg1;
2473 sign = -sign;
2474 }
2475
2476 if (arg1 > 90.0)
2477 {
2478 /* sind(180-x) = sind(x) */
2479 arg1 = 180.0 - arg1;
2480 }
2481
2482 result = sign * sind_q1(arg1);
2483
2484 if (unlikely(isinf(result)))
2486
2487 PG_RETURN_FLOAT8(result);
2488}

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), get_float8_nan(), INIT_DEGREE_CONSTANTS, PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, sign, sind_q1(), and unlikely.

◆ dsinh()

Datum dsinh ( PG_FUNCTION_ARGS  )

Definition at line 2598 of file float.c.

2599{
2601 float8 result;
2602
2603 errno = 0;
2604 result = sinh(arg1);
2605
2606 /*
2607 * if an ERANGE error occurs, it means there is an overflow. For sinh,
2608 * the result should be either -infinity or infinity, depending on the
2609 * sign of arg1.
2610 */
2611 if (errno == ERANGE)
2612 {
2613 if (arg1 < 0)
2614 result = -get_float8_infinity();
2615 else
2616 result = get_float8_infinity();
2617 }
2618
2619 PG_RETURN_FLOAT8(result);
2620}

References fb(), get_float8_infinity(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsqrt()

Datum dsqrt ( PG_FUNCTION_ARGS  )

Definition at line 1446 of file float.c.

1447{
1449 float8 result;
1450
1451 if (arg1 < 0)
1452 ereport(ERROR,
1454 errmsg("cannot take square root of a negative number")));
1455
1456 result = sqrt(arg1);
1457 if (unlikely(isinf(result)) && !isinf(arg1))
1459 if (unlikely(result == 0.0) && arg1 != 0.0)
1461
1462 PG_RETURN_FLOAT8(result);
1463}

References ereport, errcode(), errmsg(), ERROR, fb(), float_overflow_error(), float_underflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dtan()

Datum dtan ( PG_FUNCTION_ARGS  )

Definition at line 1965 of file float.c.

1966{
1968 float8 result;
1969
1970 /* Per the POSIX spec, return NaN if the input is NaN */
1971 if (isnan(arg1))
1973
1974 /* Be sure to throw an error if the input is infinite --- see dcos() */
1975 errno = 0;
1976 result = tan(arg1);
1977 if (errno != 0 || isinf(arg1))
1978 ereport(ERROR,
1980 errmsg("input is out of range")));
1981 /* Not checking for overflow because tan(pi/2) == Inf */
1982
1983 PG_RETURN_FLOAT8(result);
1984}

References ereport, errcode(), errmsg(), ERROR, fb(), get_float8_nan(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dtand()

Datum dtand ( PG_FUNCTION_ARGS  )

Definition at line 2495 of file float.c.

2496{
2498 float8 result;
2499 volatile float8 tan_arg1;
2500 int sign = 1;
2501
2502 /*
2503 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2504 * if the input is infinite.
2505 */
2506 if (isnan(arg1))
2508
2509 if (isinf(arg1))
2510 ereport(ERROR,
2512 errmsg("input is out of range")));
2513
2515
2516 /* Reduce the range of the input to [0,90] degrees */
2517 arg1 = fmod(arg1, 360.0);
2518
2519 if (arg1 < 0.0)
2520 {
2521 /* tand(-x) = -tand(x) */
2522 arg1 = -arg1;
2523 sign = -sign;
2524 }
2525
2526 if (arg1 > 180.0)
2527 {
2528 /* tand(360-x) = -tand(x) */
2529 arg1 = 360.0 - arg1;
2530 sign = -sign;
2531 }
2532
2533 if (arg1 > 90.0)
2534 {
2535 /* tand(180-x) = -tand(x) */
2536 arg1 = 180.0 - arg1;
2537 sign = -sign;
2538 }
2539
2541 result = sign * (tan_arg1 / tan_45);
2542
2543 /*
2544 * On some machines we get tand(180) = minus zero, but this isn't always
2545 * true. For portability, and because the user constituency for this
2546 * function probably doesn't want minus zero, force it to plain zero.
2547 */
2548 if (result == 0.0)
2549 result = 0.0;
2550
2551 /* Not checking for overflow because tand(90) == Inf */
2552
2553 PG_RETURN_FLOAT8(result);
2554}
static float8 tan_45
Definition float.c:49

References cosd_q1(), ereport, errcode(), errmsg(), ERROR, fb(), get_float8_nan(), INIT_DEGREE_CONSTANTS, PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, sign, sind_q1(), and tan_45.

◆ dtanh()

Datum dtanh ( PG_FUNCTION_ARGS  )

Definition at line 2652 of file float.c.

2653{
2655 float8 result;
2656
2657 /*
2658 * For tanh, we don't need an errno check because it never overflows.
2659 */
2660 result = tanh(arg1);
2661
2662 if (unlikely(isinf(result)))
2664
2665 PG_RETURN_FLOAT8(result);
2666}

References fb(), float_overflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT8, and unlikely.

◆ dtof()

Datum dtof ( PG_FUNCTION_ARGS  )

Definition at line 1195 of file float.c.

1196{
1197 float8 num = PG_GETARG_FLOAT8(0);
1198 float4 result;
1199
1200 result = (float4) num;
1201 if (unlikely(isinf(result)) && !isinf(num))
1203 if (unlikely(result == 0.0f) && num != 0.0)
1205
1206 PG_RETURN_FLOAT4(result);
1207}
#define PG_RETURN_FLOAT4(x)
Definition fmgr.h:368

References fb(), float_overflow_error(), float_underflow_error(), PG_GETARG_FLOAT8, PG_RETURN_FLOAT4, and unlikely.

◆ dtoi2()

Datum dtoi2 ( PG_FUNCTION_ARGS  )

Definition at line 1239 of file float.c.

1240{
1241 float8 num = PG_GETARG_FLOAT8(0);
1242
1243 /*
1244 * Get rid of any fractional part in the input. This is so we don't fail
1245 * on just-out-of-range values that would round into range. Note
1246 * assumption that rint() will pass through a NaN or Inf unchanged.
1247 */
1248 num = rint(num);
1249
1250 /* Range check */
1251 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT16(num)))
1252 ereport(ERROR,
1254 errmsg("smallint out of range")));
1255
1256 PG_RETURN_INT16((int16) num);
1257}
int16_t int16
Definition c.h:553
#define FLOAT8_FITS_IN_INT16(num)
Definition c.h:1103
#define PG_RETURN_INT16(x)
Definition fmgr.h:357

References ereport, errcode(), errmsg(), ERROR, fb(), FLOAT8_FITS_IN_INT16, PG_GETARG_FLOAT8, PG_RETURN_INT16, and unlikely.

◆ dtoi4()

Datum dtoi4 ( PG_FUNCTION_ARGS  )

Definition at line 1214 of file float.c.

1215{
1216 float8 num = PG_GETARG_FLOAT8(0);
1217
1218 /*
1219 * Get rid of any fractional part in the input. This is so we don't fail
1220 * on just-out-of-range values that would round into range. Note
1221 * assumption that rint() will pass through a NaN or Inf unchanged.
1222 */
1223 num = rint(num);
1224
1225 /* Range check */
1226 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT32(num)))
1227 ereport(ERROR,
1229 errmsg("integer out of range")));
1230
1231 PG_RETURN_INT32((int32) num);
1232}
#define FLOAT8_FITS_IN_INT32(num)
Definition c.h:1105
int32_t int32
Definition c.h:554

References ereport, errcode(), errmsg(), ERROR, fb(), FLOAT8_FITS_IN_INT32, PG_GETARG_FLOAT8, PG_RETURN_INT32, and unlikely.

◆ dtrunc()

Datum dtrunc ( PG_FUNCTION_ARGS  )

Definition at line 1428 of file float.c.

1429{
1431 float8 result;
1432
1433 if (arg1 >= 0)
1434 result = floor(arg1);
1435 else
1436 result = -floor(-arg1);
1437
1438 PG_RETURN_FLOAT8(result);
1439}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float48div()

Datum float48div ( PG_FUNCTION_ARGS  )

Definition at line 4002 of file float.c.

4003{
4006
4008}

References fb(), float8_div(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float48eq()

Datum float48eq ( PG_FUNCTION_ARGS  )

Definition at line 4062 of file float.c.

4063{
4066
4068}
static bool float8_eq(const float8 val1, const float8 val2)
Definition float.h:223
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360

References fb(), float8_eq(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float48ge()

Datum float48ge ( PG_FUNCTION_ARGS  )

Definition at line 4107 of file float.c.

4108{
4111
4113}
static bool float8_ge(const float8 val1, const float8 val2)
Definition float.h:283

References fb(), float8_ge(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float48gt()

Datum float48gt ( PG_FUNCTION_ARGS  )

Definition at line 4098 of file float.c.

4099{
4102
4104}
static bool float8_gt(const float8 val1, const float8 val2)
Definition float.h:271

References fb(), float8_gt(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float48le()

Datum float48le ( PG_FUNCTION_ARGS  )

Definition at line 4089 of file float.c.

4090{
4093
4095}
static bool float8_le(const float8 val1, const float8 val2)
Definition float.h:259

References fb(), float8_le(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float48lt()

Datum float48lt ( PG_FUNCTION_ARGS  )

Definition at line 4080 of file float.c.

4081{
4084
4086}
static bool float8_lt(const float8 val1, const float8 val2)
Definition float.h:247

References fb(), float8_lt(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float48mi()

Datum float48mi ( PG_FUNCTION_ARGS  )

Definition at line 3984 of file float.c.

3985{
3988
3990}
static float8 float8_mi(const float8 val1, const float8 val2)
Definition float.h:137

References fb(), float8_mi(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float48mul()

Datum float48mul ( PG_FUNCTION_ARGS  )

Definition at line 3993 of file float.c.

3994{
3997
3999}
static float8 float8_mul(const float8 val1, const float8 val2)
Definition float.h:163

References fb(), float8_mul(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float48ne()

Datum float48ne ( PG_FUNCTION_ARGS  )

Definition at line 4071 of file float.c.

4072{
4075
4077}
static bool float8_ne(const float8 val1, const float8 val2)
Definition float.h:235

References fb(), float8_ne(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float48pl()

Datum float48pl ( PG_FUNCTION_ARGS  )

Definition at line 3975 of file float.c.

3976{
3979
3981}
static float8 float8_pl(const float8 val1, const float8 val2)
Definition float.h:113

References fb(), float8_pl(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float4_accum()

Datum float4_accum ( PG_FUNCTION_ARGS  )

Definition at line 3130 of file float.c.

3131{
3133
3134 /* do computations as float8 */
3137 float8 N,
3138 Sx,
3139 Sxx,
3140 tmp;
3141
3142 transvalues = check_float8_array(transarray, "float4_accum", 3);
3143 N = transvalues[0];
3144 Sx = transvalues[1];
3145 Sxx = transvalues[2];
3146
3147 /*
3148 * Use the Youngs-Cramer algorithm to incorporate the new value into the
3149 * transition values.
3150 */
3151 N += 1.0;
3152 Sx += newval;
3153 if (transvalues[0] > 0.0)
3154 {
3155 tmp = newval * N - Sx;
3156 Sxx += tmp * tmp / (N * transvalues[0]);
3157
3158 /*
3159 * Overflow check. We only report an overflow error when finite
3160 * inputs lead to infinite results. Note also that Sxx should be NaN
3161 * if any of the inputs are infinite, so we intentionally prevent Sxx
3162 * from becoming infinite.
3163 */
3164 if (isinf(Sx) || isinf(Sxx))
3165 {
3166 if (!isinf(transvalues[1]) && !isinf(newval))
3168
3169 Sxx = get_float8_nan();
3170 }
3171 }
3172 else
3173 {
3174 /*
3175 * At the first input, we normally can leave Sxx as 0. However, if
3176 * the first input is Inf or NaN, we'd better force Sxx to NaN;
3177 * otherwise we will falsely report variance zero when there are no
3178 * more inputs.
3179 */
3180 if (isnan(newval) || isinf(newval))
3181 Sxx = get_float8_nan();
3182 }
3183
3184 /*
3185 * If we're invoked as an aggregate, we can cheat and modify our first
3186 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3187 * new array with the updated transition data and return it.
3188 */
3189 if (AggCheckCallContext(fcinfo, NULL))
3190 {
3191 transvalues[0] = N;
3192 transvalues[1] = Sx;
3193 transvalues[2] = Sxx;
3194
3196 }
3197 else
3198 {
3199 Datum transdatums[3];
3200 ArrayType *result;
3201
3205
3207
3208 PG_RETURN_ARRAYTYPE_P(result);
3209 }
3210}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
#define PG_RETURN_ARRAYTYPE_P(x)
Definition array.h:265
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static float8 * check_float8_array(ArrayType *transarray, const char *caller, int n)
Definition float.c:2933
#define newval
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition nodeAgg.c:4607
#define Float8GetDatumFast(X)
Definition postgres.h:537
uint64_t Datum
Definition postgres.h:70

References AggCheckCallContext(), check_float8_array(), construct_array_builtin(), fb(), Float8GetDatumFast, float_overflow_error(), get_float8_nan(), newval, PG_GETARG_ARRAYTYPE_P, PG_GETARG_FLOAT4, and PG_RETURN_ARRAYTYPE_P.

◆ float4_cmp_internal()

int float4_cmp_internal ( float4  a,
float4  b 
)

Definition at line 816 of file float.c.

817{
818 if (float4_gt(a, b))
819 return 1;
820 if (float4_lt(a, b))
821 return -1;
822 return 0;
823}
static bool float4_lt(const float4 val1, const float4 val2)
Definition float.h:241
static bool float4_gt(const float4 val1, const float4 val2)
Definition float.h:265
int b
Definition isn.c:74
int a
Definition isn.c:73

References a, b, float4_gt(), and float4_lt().

Referenced by btfloat4cmp(), btfloat4fastcmp(), and gbt_float4_ssup_cmp().

◆ float4abs()

Datum float4abs ( PG_FUNCTION_ARGS  )

Definition at line 591 of file float.c.

592{
594
596}

References fb(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4div()

Datum float4div ( PG_FUNCTION_ARGS  )

Definition at line 755 of file float.c.

756{
759
761}
static float4 float4_div(const float4 val1, const float4 val2)
Definition float.h:177

References fb(), float4_div(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4eq()

Datum float4eq ( PG_FUNCTION_ARGS  )

Definition at line 826 of file float.c.

827{
830
832}
static bool float4_eq(const float4 val1, const float4 val2)
Definition float.h:217

References fb(), float4_eq(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4ge()

Datum float4ge ( PG_FUNCTION_ARGS  )

Definition at line 871 of file float.c.

872{
875
877}
static bool float4_ge(const float4 val1, const float4 val2)
Definition float.h:277

References fb(), float4_ge(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4gt()

Datum float4gt ( PG_FUNCTION_ARGS  )

Definition at line 862 of file float.c.

References fb(), float4_gt(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4in()

Datum float4in ( PG_FUNCTION_ARGS  )

Definition at line 164 of file float.c.

165{
166 char *num = PG_GETARG_CSTRING(0);
167
168 PG_RETURN_FLOAT4(float4in_internal(num, NULL, "real", num,
169 fcinfo->context));
170}
float4 float4in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:183
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278

References fb(), float4in_internal(), PG_GETARG_CSTRING, and PG_RETURN_FLOAT4.

Referenced by numeric_float4().

◆ float4in_internal()

float4 float4in_internal ( char num,
char **  endptr_p,
const char type_name,
const char orig_string,
struct Node escontext 
)

Definition at line 183 of file float.c.

186{
187 float val;
188 char *endptr;
189
190 /*
191 * endptr points to the first character _after_ the sequence we recognized
192 * as a valid floating point number. orig_string points to the original
193 * input string.
194 */
195
196 /* skip leading whitespace */
197 while (*num != '\0' && isspace((unsigned char) *num))
198 num++;
199
200 /*
201 * Check for an empty-string input to begin with, to avoid the vagaries of
202 * strtod() on different platforms.
203 */
204 if (*num == '\0')
205 ereturn(escontext, 0,
207 errmsg("invalid input syntax for type %s: \"%s\"",
208 type_name, orig_string)));
209
210 errno = 0;
211 val = strtof(num, &endptr);
212
213 /* did we not see anything that looks like a double? */
214 if (endptr == num || errno != 0)
215 {
216 int save_errno = errno;
217
218 /*
219 * C99 requires that strtof() accept NaN, [+-]Infinity, and [+-]Inf,
220 * but not all platforms support all of these (and some accept them
221 * but set ERANGE anyway...) Therefore, we check for these inputs
222 * ourselves if strtof() fails.
223 *
224 * Note: C99 also requires hexadecimal input as well as some extended
225 * forms of NaN, but we consider these forms unportable and don't try
226 * to support them. You can use 'em if your strtof() takes 'em.
227 */
228 if (pg_strncasecmp(num, "NaN", 3) == 0)
229 {
231 endptr = num + 3;
232 }
233 else if (pg_strncasecmp(num, "Infinity", 8) == 0)
234 {
236 endptr = num + 8;
237 }
238 else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
239 {
241 endptr = num + 9;
242 }
243 else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
244 {
246 endptr = num + 9;
247 }
248 else if (pg_strncasecmp(num, "inf", 3) == 0)
249 {
251 endptr = num + 3;
252 }
253 else if (pg_strncasecmp(num, "+inf", 4) == 0)
254 {
256 endptr = num + 4;
257 }
258 else if (pg_strncasecmp(num, "-inf", 4) == 0)
259 {
261 endptr = num + 4;
262 }
263 else if (save_errno == ERANGE)
264 {
265 /*
266 * Some platforms return ERANGE for denormalized numbers (those
267 * that are not zero, but are too close to zero to have full
268 * precision). We'd prefer not to throw error for that, so try to
269 * detect whether it's a "real" out-of-range condition by checking
270 * to see if the result is zero or huge.
271 */
272 if (val == 0.0 ||
273#if !defined(HUGE_VALF)
274 isinf(val)
275#else
276 (val >= HUGE_VALF || val <= -HUGE_VALF)
277#endif
278 )
279 {
280 /* see comments in float8in_internal for rationale */
281 char *errnumber = pstrdup(num);
282
283 errnumber[endptr - num] = '\0';
284
285 ereturn(escontext, 0,
287 errmsg("\"%s\" is out of range for type real",
288 errnumber)));
289 }
290 }
291 else
292 ereturn(escontext, 0,
294 errmsg("invalid input syntax for type %s: \"%s\"",
295 type_name, orig_string)));
296 }
297
298 /* skip trailing whitespace */
299 while (*endptr != '\0' && isspace((unsigned char) *endptr))
300 endptr++;
301
302 /* report stopping point if wanted, else complain if not end of string */
303 if (endptr_p)
304 *endptr_p = endptr;
305 else if (*endptr != '\0')
306 ereturn(escontext, 0,
308 errmsg("invalid input syntax for type %s: \"%s\"",
309 type_name, orig_string)));
310
311 return val;
312}
#define ereturn(context, dummy_value,...)
Definition elog.h:278
static float4 get_float4_infinity(void)
Definition float.h:58
static float4 get_float4_nan(void)
Definition float.h:77
long val
Definition informix.c:689
char * pstrdup(const char *in)
Definition mcxt.c:1781
int pg_strncasecmp(const char *s1, const char *s2, size_t n)

References ereturn, errcode(), errmsg(), fb(), get_float4_infinity(), get_float4_nan(), pg_strncasecmp(), pstrdup(), and val.

Referenced by float4in().

◆ float4larger()

Datum float4larger ( PG_FUNCTION_ARGS  )

Definition at line 620 of file float.c.

621{
624 float4 result;
625
626 if (float4_gt(arg1, arg2))
627 result = arg1;
628 else
629 result = arg2;
630 PG_RETURN_FLOAT4(result);
631}

References fb(), float4_gt(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4le()

Datum float4le ( PG_FUNCTION_ARGS  )

Definition at line 853 of file float.c.

854{
857
859}
static bool float4_le(const float4 val1, const float4 val2)
Definition float.h:253

References fb(), float4_le(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4lt()

Datum float4lt ( PG_FUNCTION_ARGS  )

Definition at line 844 of file float.c.

References fb(), float4_lt(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4mi()

Datum float4mi ( PG_FUNCTION_ARGS  )

Definition at line 737 of file float.c.

738{
741
743}
static float4 float4_mi(const float4 val1, const float4 val2)
Definition float.h:125

References fb(), float4_mi(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4mul()

Datum float4mul ( PG_FUNCTION_ARGS  )

Definition at line 746 of file float.c.

747{
750
752}
static float4 float4_mul(const float4 val1, const float4 val2)
Definition float.h:149

References fb(), float4_mul(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4ne()

Datum float4ne ( PG_FUNCTION_ARGS  )

Definition at line 835 of file float.c.

836{
839
841}
static bool float4_ne(const float4 val1, const float4 val2)
Definition float.h:229

References fb(), float4_ne(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4out()

Datum float4out ( PG_FUNCTION_ARGS  )

Definition at line 319 of file float.c.

320{
321 float4 num = PG_GETARG_FLOAT4(0);
322 char *ascii = (char *) palloc(32);
324
325 if (extra_float_digits > 0)
326 {
329 }
330
331 (void) pg_strfromd(ascii, 32, ndig, num);
333}
int float_to_shortest_decimal_buf(float f, char *result)
Definition f2s.c:780
int extra_float_digits
Definition float.c:40
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
void * palloc(Size size)
Definition mcxt.c:1387
Datum ascii(PG_FUNCTION_ARGS)
int pg_strfromd(char *str, size_t count, int precision, double value)
Definition snprintf.c:1276

References ascii(), extra_float_digits, fb(), float_to_shortest_decimal_buf(), palloc(), PG_GETARG_FLOAT4, PG_RETURN_CSTRING, and pg_strfromd().

◆ float4pl()

Datum float4pl ( PG_FUNCTION_ARGS  )

Definition at line 728 of file float.c.

729{
732
734}
static float4 float4_pl(const float4 val1, const float4 val2)
Definition float.h:101

References fb(), float4_pl(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4recv()

Datum float4recv ( PG_FUNCTION_ARGS  )

Definition at line 339 of file float.c.

340{
342
344}
static char buf[DEFAULT_XLOG_SEG_SIZE]
float4 pq_getmsgfloat4(StringInfo msg)
Definition pqformat.c:468
struct StringInfoData * StringInfo
Definition string.h:15

References buf, PG_GETARG_POINTER, PG_RETURN_FLOAT4, and pq_getmsgfloat4().

◆ float4send()

Datum float4send ( PG_FUNCTION_ARGS  )

Definition at line 350 of file float.c.

351{
352 float4 num = PG_GETARG_FLOAT4(0);
354
356 pq_sendfloat4(&buf, num);
358}
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
void pq_sendfloat4(StringInfo buf, float4 f)
Definition pqformat.c:252
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345

References buf, PG_GETARG_FLOAT4, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), and pq_sendfloat4().

◆ float4smaller()

Datum float4smaller ( PG_FUNCTION_ARGS  )

Definition at line 634 of file float.c.

635{
638 float4 result;
639
640 if (float4_lt(arg1, arg2))
641 result = arg1;
642 else
643 result = arg2;
644 PG_RETURN_FLOAT4(result);
645}

References fb(), float4_lt(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4um()

Datum float4um ( PG_FUNCTION_ARGS  )

Definition at line 602 of file float.c.

603{
605 float4 result;
606
607 result = -arg1;
608 PG_RETURN_FLOAT4(result);
609}

References fb(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4up()

Datum float4up ( PG_FUNCTION_ARGS  )

Definition at line 612 of file float.c.

613{
615
617}
Datum arg
Definition elog.c:1322

References arg, PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float84div()

Datum float84div ( PG_FUNCTION_ARGS  )

Definition at line 4044 of file float.c.

4045{
4048
4050}

References fb(), float8_div(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float84eq()

Datum float84eq ( PG_FUNCTION_ARGS  )

Definition at line 4119 of file float.c.

4120{
4123
4125}

References fb(), float8_eq(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float84ge()

Datum float84ge ( PG_FUNCTION_ARGS  )

Definition at line 4164 of file float.c.

4165{
4168
4170}

References fb(), float8_ge(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float84gt()

Datum float84gt ( PG_FUNCTION_ARGS  )

Definition at line 4155 of file float.c.

4156{
4159
4161}

References fb(), float8_gt(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float84le()

Datum float84le ( PG_FUNCTION_ARGS  )

Definition at line 4146 of file float.c.

4147{
4150
4152}

References fb(), float8_le(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float84lt()

Datum float84lt ( PG_FUNCTION_ARGS  )

Definition at line 4137 of file float.c.

4138{
4141
4143}

References fb(), float8_lt(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float84mi()

Datum float84mi ( PG_FUNCTION_ARGS  )

Definition at line 4026 of file float.c.

4027{
4030
4032}

References fb(), float8_mi(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float84mul()

Datum float84mul ( PG_FUNCTION_ARGS  )

Definition at line 4035 of file float.c.

4036{
4039
4041}

References fb(), float8_mul(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float84ne()

Datum float84ne ( PG_FUNCTION_ARGS  )

Definition at line 4128 of file float.c.

4129{
4132
4134}

References fb(), float8_ne(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float84pl()

Datum float84pl ( PG_FUNCTION_ARGS  )

Definition at line 4017 of file float.c.

4018{
4021
4023}

References fb(), float8_pl(), PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8_accum()

Datum float8_accum ( PG_FUNCTION_ARGS  )

Definition at line 3049 of file float.c.

3050{
3054 float8 N,
3055 Sx,
3056 Sxx,
3057 tmp;
3058
3059 transvalues = check_float8_array(transarray, "float8_accum", 3);
3060 N = transvalues[0];
3061 Sx = transvalues[1];
3062 Sxx = transvalues[2];
3063
3064 /*
3065 * Use the Youngs-Cramer algorithm to incorporate the new value into the
3066 * transition values.
3067 */
3068 N += 1.0;
3069 Sx += newval;
3070 if (transvalues[0] > 0.0)
3071 {
3072 tmp = newval * N - Sx;
3073 Sxx += tmp * tmp / (N * transvalues[0]);
3074
3075 /*
3076 * Overflow check. We only report an overflow error when finite
3077 * inputs lead to infinite results. Note also that Sxx should be NaN
3078 * if any of the inputs are infinite, so we intentionally prevent Sxx
3079 * from becoming infinite.
3080 */
3081 if (isinf(Sx) || isinf(Sxx))
3082 {
3083 if (!isinf(transvalues[1]) && !isinf(newval))
3085
3086 Sxx = get_float8_nan();
3087 }
3088 }
3089 else
3090 {
3091 /*
3092 * At the first input, we normally can leave Sxx as 0. However, if
3093 * the first input is Inf or NaN, we'd better force Sxx to NaN;
3094 * otherwise we will falsely report variance zero when there are no
3095 * more inputs.
3096 */
3097 if (isnan(newval) || isinf(newval))
3098 Sxx = get_float8_nan();
3099 }
3100
3101 /*
3102 * If we're invoked as an aggregate, we can cheat and modify our first
3103 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3104 * new array with the updated transition data and return it.
3105 */
3106 if (AggCheckCallContext(fcinfo, NULL))
3107 {
3108 transvalues[0] = N;
3109 transvalues[1] = Sx;
3110 transvalues[2] = Sxx;
3111
3113 }
3114 else
3115 {
3116 Datum transdatums[3];
3117 ArrayType *result;
3118
3122
3124
3125 PG_RETURN_ARRAYTYPE_P(result);
3126 }
3127}

References AggCheckCallContext(), check_float8_array(), construct_array_builtin(), fb(), Float8GetDatumFast, float_overflow_error(), get_float8_nan(), newval, PG_GETARG_ARRAYTYPE_P, PG_GETARG_FLOAT8, and PG_RETURN_ARRAYTYPE_P.

◆ float8_avg()

Datum float8_avg ( PG_FUNCTION_ARGS  )

Definition at line 3213 of file float.c.

3214{
3217 float8 N,
3218 Sx;
3219
3220 transvalues = check_float8_array(transarray, "float8_avg", 3);
3221 N = transvalues[0];
3222 Sx = transvalues[1];
3223 /* ignore Sxx */
3224
3225 /* SQL defines AVG of no values to be NULL */
3226 if (N == 0.0)
3228
3229 PG_RETURN_FLOAT8(Sx / N);
3230}
#define PG_RETURN_NULL()
Definition fmgr.h:346

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_cmp_internal()

int float8_cmp_internal ( float8  a,
float8  b 
)

Definition at line 910 of file float.c.

911{
912 if (float8_gt(a, b))
913 return 1;
914 if (float8_lt(a, b))
915 return -1;
916 return 0;
917}

References a, b, float8_gt(), and float8_lt().

Referenced by btfloat48cmp(), btfloat84cmp(), btfloat8cmp(), btfloat8fastcmp(), common_entry_cmp(), gbt_float8_ssup_cmp(), interval_cmp_lower(), interval_cmp_upper(), and pairingheap_GISTSearchItem_cmp().

◆ float8_combine()

Datum float8_combine ( PG_FUNCTION_ARGS  )

Definition at line 2957 of file float.c.

2958{
2963 float8 N1,
2964 Sx1,
2965 Sxx1,
2966 N2,
2967 Sx2,
2968 Sxx2,
2969 tmp,
2970 N,
2971 Sx,
2972 Sxx;
2973
2974 transvalues1 = check_float8_array(transarray1, "float8_combine", 3);
2975 transvalues2 = check_float8_array(transarray2, "float8_combine", 3);
2976
2977 N1 = transvalues1[0];
2978 Sx1 = transvalues1[1];
2979 Sxx1 = transvalues1[2];
2980
2981 N2 = transvalues2[0];
2982 Sx2 = transvalues2[1];
2983 Sxx2 = transvalues2[2];
2984
2985 /*--------------------
2986 * The transition values combine using a generalization of the
2987 * Youngs-Cramer algorithm as follows:
2988 *
2989 * N = N1 + N2
2990 * Sx = Sx1 + Sx2
2991 * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N;
2992 *
2993 * It's worth handling the special cases N1 = 0 and N2 = 0 separately
2994 * since those cases are trivial, and we then don't need to worry about
2995 * division-by-zero errors in the general case.
2996 *--------------------
2997 */
2998 if (N1 == 0.0)
2999 {
3000 N = N2;
3001 Sx = Sx2;
3002 Sxx = Sxx2;
3003 }
3004 else if (N2 == 0.0)
3005 {
3006 N = N1;
3007 Sx = Sx1;
3008 Sxx = Sxx1;
3009 }
3010 else
3011 {
3012 N = N1 + N2;
3013 Sx = float8_pl(Sx1, Sx2);
3014 tmp = Sx1 / N1 - Sx2 / N2;
3015 Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp * tmp / N;
3016 if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3018 }
3019
3020 /*
3021 * If we're invoked as an aggregate, we can cheat and modify our first
3022 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3023 * new array with the updated transition data and return it.
3024 */
3025 if (AggCheckCallContext(fcinfo, NULL))
3026 {
3027 transvalues1[0] = N;
3028 transvalues1[1] = Sx;
3029 transvalues1[2] = Sxx;
3030
3032 }
3033 else
3034 {
3035 Datum transdatums[3];
3036 ArrayType *result;
3037
3041
3043
3044 PG_RETURN_ARRAYTYPE_P(result);
3045 }
3046}

References AggCheckCallContext(), check_float8_array(), construct_array_builtin(), fb(), float8_pl(), Float8GetDatumFast, float_overflow_error(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_ARRAYTYPE_P, and unlikely.

◆ float8_corr()

Datum float8_corr ( PG_FUNCTION_ARGS  )

Definition at line 3817 of file float.c.

3818{
3821 float8 N,
3822 Sxx,
3823 Syy,
3824 Sxy,
3825 product,
3827 result;
3828
3829 transvalues = check_float8_array(transarray, "float8_corr", 8);
3830 N = transvalues[0];
3831 Sxx = transvalues[2];
3832 Syy = transvalues[4];
3833 Sxy = transvalues[5];
3834
3835 /* if N is 0 we should return NULL */
3836 if (N < 1.0)
3838
3839 /* Note that Sxx and Syy are guaranteed to be non-negative */
3840
3841 /* per spec, return NULL for horizontal and vertical lines */
3842 if (Sxx == 0 || Syy == 0)
3844
3845 /*
3846 * The product Sxx * Syy might underflow or overflow. If so, we can
3847 * recover by computing sqrt(Sxx) * sqrt(Syy) instead of sqrt(Sxx * Syy).
3848 * However, the double sqrt() calculation is a bit slower and less
3849 * accurate, so don't do it if we don't have to.
3850 */
3851 product = Sxx * Syy;
3852 if (product == 0 || isinf(product))
3853 sqrtproduct = sqrt(Sxx) * sqrt(Syy);
3854 else
3856 result = Sxy / sqrtproduct;
3857
3858 /*
3859 * Despite all these precautions, this formula can yield results outside
3860 * [-1, 1] due to roundoff error. Clamp it to the expected range.
3861 */
3862 if (result < -1)
3863 result = -1;
3864 else if (result > 1)
3865 result = 1;
3866
3867 PG_RETURN_FLOAT8(result);
3868}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_covar_pop()

Datum float8_covar_pop ( PG_FUNCTION_ARGS  )

Definition at line 3779 of file float.c.

3780{
3783 float8 N,
3784 Sxy;
3785
3786 transvalues = check_float8_array(transarray, "float8_covar_pop", 8);
3787 N = transvalues[0];
3788 Sxy = transvalues[5];
3789
3790 /* if N is 0 we should return NULL */
3791 if (N < 1.0)
3793
3794 PG_RETURN_FLOAT8(Sxy / N);
3795}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_covar_samp()

Datum float8_covar_samp ( PG_FUNCTION_ARGS  )

Definition at line 3798 of file float.c.

3799{
3802 float8 N,
3803 Sxy;
3804
3805 transvalues = check_float8_array(transarray, "float8_covar_samp", 8);
3806 N = transvalues[0];
3807 Sxy = transvalues[5];
3808
3809 /* if N is <= 1 we should return NULL */
3810 if (N < 2.0)
3812
3813 PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3814}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_regr_accum()

Datum float8_regr_accum ( PG_FUNCTION_ARGS  )

Definition at line 3354 of file float.c.

3355{
3360 float8 N,
3361 Sx,
3362 Sxx,
3363 Sy,
3364 Syy,
3365 Sxy,
3366 commonX,
3367 commonY,
3368 tmpX,
3369 tmpY,
3370 scale;
3371
3372 transvalues = check_float8_array(transarray, "float8_regr_accum", 8);
3373 N = transvalues[0];
3374 Sx = transvalues[1];
3375 Sxx = transvalues[2];
3376 Sy = transvalues[3];
3377 Syy = transvalues[4];
3378 Sxy = transvalues[5];
3379 commonX = transvalues[6];
3380 commonY = transvalues[7];
3381
3382 /*
3383 * Use the Youngs-Cramer algorithm to incorporate the new values into the
3384 * transition values.
3385 */
3386 N += 1.0;
3387 Sx += newvalX;
3388 Sy += newvalY;
3389 if (transvalues[0] > 0.0)
3390 {
3391 /*
3392 * Check to see if we have seen distinct inputs. We can use a test
3393 * that's a bit cheaper than float8_ne() because if commonX is already
3394 * NaN, it does not matter whether the != test returns true or not.
3395 */
3396 if (newvalX != commonX || isnan(newvalX))
3398 if (newvalY != commonY || isnan(newvalY))
3400
3401 tmpX = newvalX * N - Sx;
3402 tmpY = newvalY * N - Sy;
3403 scale = 1.0 / (N * transvalues[0]);
3404
3405 /*
3406 * If we have not seen distinct inputs, then Sxx, Syy, and/or Sxy
3407 * should remain zero (since Sx's exact value would be N * commonX,
3408 * etc). Updating them would just create the possibility of injecting
3409 * roundoff error, and we need exact zero results so that the final
3410 * functions will return NULL in the right cases.
3411 */
3412 if (isnan(commonX))
3413 Sxx += tmpX * tmpX * scale;
3414 if (isnan(commonY))
3415 Syy += tmpY * tmpY * scale;
3416 if (isnan(commonX) && isnan(commonY))
3417 Sxy += tmpX * tmpY * scale;
3418
3419 /*
3420 * Overflow check. We only report an overflow error when finite
3421 * inputs lead to infinite results. Note also that Sxx, Syy and Sxy
3422 * should be NaN if any of the relevant inputs are infinite, so we
3423 * intentionally prevent them from becoming infinite.
3424 */
3425 if (isinf(Sx) || isinf(Sxx) || isinf(Sy) || isinf(Syy) || isinf(Sxy))
3426 {
3427 if (((isinf(Sx) || isinf(Sxx)) &&
3428 !isinf(transvalues[1]) && !isinf(newvalX)) ||
3429 ((isinf(Sy) || isinf(Syy)) &&
3430 !isinf(transvalues[3]) && !isinf(newvalY)) ||
3431 (isinf(Sxy) &&
3432 !isinf(transvalues[1]) && !isinf(newvalX) &&
3433 !isinf(transvalues[3]) && !isinf(newvalY)))
3435
3436 if (isinf(Sxx))
3437 Sxx = get_float8_nan();
3438 if (isinf(Syy))
3439 Syy = get_float8_nan();
3440 if (isinf(Sxy))
3441 Sxy = get_float8_nan();
3442 }
3443 }
3444 else
3445 {
3446 /*
3447 * At the first input, we normally can leave Sxx et al as 0. However,
3448 * if the first input is Inf or NaN, we'd better force the dependent
3449 * sums to NaN; otherwise we will falsely report variance zero when
3450 * there are no more inputs.
3451 */
3452 if (isnan(newvalX) || isinf(newvalX))
3453 Sxx = Sxy = get_float8_nan();
3454 if (isnan(newvalY) || isinf(newvalY))
3455 Syy = Sxy = get_float8_nan();
3456
3457 commonX = newvalX;
3458 commonY = newvalY;
3459 }
3460
3461 /*
3462 * If we're invoked as an aggregate, we can cheat and modify our first
3463 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3464 * new array with the updated transition data and return it.
3465 */
3466 if (AggCheckCallContext(fcinfo, NULL))
3467 {
3468 transvalues[0] = N;
3469 transvalues[1] = Sx;
3470 transvalues[2] = Sxx;
3471 transvalues[3] = Sy;
3472 transvalues[4] = Syy;
3473 transvalues[5] = Sxy;
3474 transvalues[6] = commonX;
3475 transvalues[7] = commonY;
3476
3478 }
3479 else
3480 {
3481 Datum transdatums[8];
3482 ArrayType *result;
3483
3492
3494
3495 PG_RETURN_ARRAYTYPE_P(result);
3496 }
3497}
static int scale
Definition pgbench.c:182

References AggCheckCallContext(), check_float8_array(), construct_array_builtin(), fb(), Float8GetDatumFast, float_overflow_error(), get_float8_nan(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_FLOAT8, PG_RETURN_ARRAYTYPE_P, and scale.

◆ float8_regr_avgx()

Datum float8_regr_avgx ( PG_FUNCTION_ARGS  )

Definition at line 3729 of file float.c.

3730{
3733 float8 N,
3734 Sx,
3735 commonX;
3736
3737 transvalues = check_float8_array(transarray, "float8_regr_avgx", 8);
3738 N = transvalues[0];
3739 Sx = transvalues[1];
3740 commonX = transvalues[6];
3741
3742 /* if N is 0 we should return NULL */
3743 if (N < 1.0)
3745
3746 /* if all inputs were the same just return that, avoiding roundoff error */
3747 if (!isnan(commonX))
3749
3750 PG_RETURN_FLOAT8(Sx / N);
3751}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_regr_avgy()

Datum float8_regr_avgy ( PG_FUNCTION_ARGS  )

Definition at line 3754 of file float.c.

3755{
3758 float8 N,
3759 Sy,
3760 commonY;
3761
3762 transvalues = check_float8_array(transarray, "float8_regr_avgy", 8);
3763 N = transvalues[0];
3764 Sy = transvalues[3];
3765 commonY = transvalues[7];
3766
3767 /* if N is 0 we should return NULL */
3768 if (N < 1.0)
3770
3771 /* if all inputs were the same just return that, avoiding roundoff error */
3772 if (!isnan(commonY))
3774
3775 PG_RETURN_FLOAT8(Sy / N);
3776}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_regr_combine()

Datum float8_regr_combine ( PG_FUNCTION_ARGS  )

Definition at line 3508 of file float.c.

3509{
3514 float8 N1,
3515 Sx1,
3516 Sxx1,
3517 Sy1,
3518 Syy1,
3519 Sxy1,
3520 Cx1,
3521 Cy1,
3522 N2,
3523 Sx2,
3524 Sxx2,
3525 Sy2,
3526 Syy2,
3527 Sxy2,
3528 Cx2,
3529 Cy2,
3530 tmp1,
3531 tmp2,
3532 N,
3533 Sx,
3534 Sxx,
3535 Sy,
3536 Syy,
3537 Sxy,
3538 Cx,
3539 Cy;
3540
3541 transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 8);
3542 transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 8);
3543
3544 N1 = transvalues1[0];
3545 Sx1 = transvalues1[1];
3546 Sxx1 = transvalues1[2];
3547 Sy1 = transvalues1[3];
3548 Syy1 = transvalues1[4];
3549 Sxy1 = transvalues1[5];
3550 Cx1 = transvalues1[6];
3551 Cy1 = transvalues1[7];
3552
3553 N2 = transvalues2[0];
3554 Sx2 = transvalues2[1];
3555 Sxx2 = transvalues2[2];
3556 Sy2 = transvalues2[3];
3557 Syy2 = transvalues2[4];
3558 Sxy2 = transvalues2[5];
3559 Cx2 = transvalues2[6];
3560 Cy2 = transvalues2[7];
3561
3562 /*--------------------
3563 * The transition values combine using a generalization of the
3564 * Youngs-Cramer algorithm as follows:
3565 *
3566 * N = N1 + N2
3567 * Sx = Sx1 + Sx2
3568 * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N
3569 * Sy = Sy1 + Sy2
3570 * Syy = Syy1 + Syy2 + N1 * N2 * (Sy1/N1 - Sy2/N2)^2 / N
3571 * Sxy = Sxy1 + Sxy2 + N1 * N2 * (Sx1/N1 - Sx2/N2) * (Sy1/N1 - Sy2/N2) / N
3572 *
3573 * It's worth handling the special cases N1 = 0 and N2 = 0 separately
3574 * since those cases are trivial, and we then don't need to worry about
3575 * division-by-zero errors in the general case.
3576 *--------------------
3577 */
3578 if (N1 == 0.0)
3579 {
3580 N = N2;
3581 Sx = Sx2;
3582 Sxx = Sxx2;
3583 Sy = Sy2;
3584 Syy = Syy2;
3585 Sxy = Sxy2;
3586 Cx = Cx2;
3587 Cy = Cy2;
3588 }
3589 else if (N2 == 0.0)
3590 {
3591 N = N1;
3592 Sx = Sx1;
3593 Sxx = Sxx1;
3594 Sy = Sy1;
3595 Syy = Syy1;
3596 Sxy = Sxy1;
3597 Cx = Cx1;
3598 Cy = Cy1;
3599 }
3600 else
3601 {
3602 N = N1 + N2;
3603 Sx = float8_pl(Sx1, Sx2);
3604 tmp1 = Sx1 / N1 - Sx2 / N2;
3605 Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp1 * tmp1 / N;
3606 if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3608 Sy = float8_pl(Sy1, Sy2);
3609 tmp2 = Sy1 / N1 - Sy2 / N2;
3610 Syy = Syy1 + Syy2 + N1 * N2 * tmp2 * tmp2 / N;
3611 if (unlikely(isinf(Syy)) && !isinf(Syy1) && !isinf(Syy2))
3613 Sxy = Sxy1 + Sxy2 + N1 * N2 * tmp1 * tmp2 / N;
3614 if (unlikely(isinf(Sxy)) && !isinf(Sxy1) && !isinf(Sxy2))
3616 if (float8_eq(Cx1, Cx2))
3617 Cx = Cx1;
3618 else
3619 Cx = get_float8_nan();
3620 if (float8_eq(Cy1, Cy2))
3621 Cy = Cy1;
3622 else
3623 Cy = get_float8_nan();
3624 }
3625
3626 /*
3627 * If we're invoked as an aggregate, we can cheat and modify our first
3628 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3629 * new array with the updated transition data and return it.
3630 */
3631 if (AggCheckCallContext(fcinfo, NULL))
3632 {
3633 transvalues1[0] = N;
3634 transvalues1[1] = Sx;
3635 transvalues1[2] = Sxx;
3636 transvalues1[3] = Sy;
3637 transvalues1[4] = Syy;
3638 transvalues1[5] = Sxy;
3639 transvalues1[6] = Cx;
3640 transvalues1[7] = Cy;
3641
3643 }
3644 else
3645 {
3646 Datum transdatums[8];
3647 ArrayType *result;
3648
3657
3659
3660 PG_RETURN_ARRAYTYPE_P(result);
3661 }
3662}

References AggCheckCallContext(), check_float8_array(), construct_array_builtin(), fb(), float8_eq(), float8_pl(), Float8GetDatumFast, float_overflow_error(), get_float8_nan(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_ARRAYTYPE_P, and unlikely.

◆ float8_regr_intercept()

Datum float8_regr_intercept ( PG_FUNCTION_ARGS  )

Definition at line 3931 of file float.c.

3932{
3935 float8 N,
3936 Sx,
3937 Sxx,
3938 Sy,
3939 Sxy;
3940
3941 transvalues = check_float8_array(transarray, "float8_regr_intercept", 8);
3942 N = transvalues[0];
3943 Sx = transvalues[1];
3944 Sxx = transvalues[2];
3945 Sy = transvalues[3];
3946 Sxy = transvalues[5];
3947
3948 /* if N is 0 we should return NULL */
3949 if (N < 1.0)
3951
3952 /* Note that Sxx is guaranteed to be non-negative */
3953
3954 /* per spec, return NULL for a vertical line */
3955 if (Sxx == 0)
3957
3958 PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
3959}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_regr_r2()

Datum float8_regr_r2 ( PG_FUNCTION_ARGS  )

Definition at line 3871 of file float.c.

3872{
3875 float8 N,
3876 Sxx,
3877 Syy,
3878 Sxy;
3879
3880 transvalues = check_float8_array(transarray, "float8_regr_r2", 8);
3881 N = transvalues[0];
3882 Sxx = transvalues[2];
3883 Syy = transvalues[4];
3884 Sxy = transvalues[5];
3885
3886 /* if N is 0 we should return NULL */
3887 if (N < 1.0)
3889
3890 /* Note that Sxx and Syy are guaranteed to be non-negative */
3891
3892 /* per spec, return NULL for a vertical line */
3893 if (Sxx == 0)
3895
3896 /* per spec, return 1.0 for a horizontal line */
3897 if (Syy == 0)
3898 PG_RETURN_FLOAT8(1.0);
3899
3900 PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3901}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_regr_slope()

Datum float8_regr_slope ( PG_FUNCTION_ARGS  )

Definition at line 3904 of file float.c.

3905{
3908 float8 N,
3909 Sxx,
3910 Sxy;
3911
3912 transvalues = check_float8_array(transarray, "float8_regr_slope", 8);
3913 N = transvalues[0];
3914 Sxx = transvalues[2];
3915 Sxy = transvalues[5];
3916
3917 /* if N is 0 we should return NULL */
3918 if (N < 1.0)
3920
3921 /* Note that Sxx is guaranteed to be non-negative */
3922
3923 /* per spec, return NULL for a vertical line */
3924 if (Sxx == 0)
3926
3928}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_regr_sxx()

Datum float8_regr_sxx ( PG_FUNCTION_ARGS  )

Definition at line 3666 of file float.c.

3667{
3670 float8 N,
3671 Sxx;
3672
3673 transvalues = check_float8_array(transarray, "float8_regr_sxx", 8);
3674 N = transvalues[0];
3675 Sxx = transvalues[2];
3676
3677 /* if N is 0 we should return NULL */
3678 if (N < 1.0)
3680
3681 /* Note that Sxx is guaranteed to be non-negative */
3682
3684}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_regr_sxy()

Datum float8_regr_sxy ( PG_FUNCTION_ARGS  )

Definition at line 3708 of file float.c.

3709{
3712 float8 N,
3713 Sxy;
3714
3715 transvalues = check_float8_array(transarray, "float8_regr_sxy", 8);
3716 N = transvalues[0];
3717 Sxy = transvalues[5];
3718
3719 /* if N is 0 we should return NULL */
3720 if (N < 1.0)
3722
3723 /* A negative result is valid here */
3724
3726}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_regr_syy()

Datum float8_regr_syy ( PG_FUNCTION_ARGS  )

Definition at line 3687 of file float.c.

3688{
3691 float8 N,
3692 Syy;
3693
3694 transvalues = check_float8_array(transarray, "float8_regr_syy", 8);
3695 N = transvalues[0];
3696 Syy = transvalues[4];
3697
3698 /* if N is 0 we should return NULL */
3699 if (N < 1.0)
3701
3702 /* Note that Syy is guaranteed to be non-negative */
3703
3705}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_stddev_pop()

Datum float8_stddev_pop ( PG_FUNCTION_ARGS  )

Definition at line 3277 of file float.c.

3278{
3281 float8 N,
3282 Sxx;
3283
3284 transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
3285 N = transvalues[0];
3286 /* ignore Sx */
3287 Sxx = transvalues[2];
3288
3289 /* Population stddev is undefined when N is 0, so return NULL */
3290 if (N == 0.0)
3292
3293 /* Note that Sxx is guaranteed to be non-negative */
3294
3296}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_stddev_samp()

Datum float8_stddev_samp ( PG_FUNCTION_ARGS  )

Definition at line 3299 of file float.c.

3300{
3303 float8 N,
3304 Sxx;
3305
3306 transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
3307 N = transvalues[0];
3308 /* ignore Sx */
3309 Sxx = transvalues[2];
3310
3311 /* Sample stddev is undefined when N is 0 or 1, so return NULL */
3312 if (N <= 1.0)
3314
3315 /* Note that Sxx is guaranteed to be non-negative */
3316
3317 PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0)));
3318}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_var_pop()

Datum float8_var_pop ( PG_FUNCTION_ARGS  )

Definition at line 3233 of file float.c.

3234{
3237 float8 N,
3238 Sxx;
3239
3240 transvalues = check_float8_array(transarray, "float8_var_pop", 3);
3241 N = transvalues[0];
3242 /* ignore Sx */
3243 Sxx = transvalues[2];
3244
3245 /* Population variance is undefined when N is 0, so return NULL */
3246 if (N == 0.0)
3248
3249 /* Note that Sxx is guaranteed to be non-negative */
3250
3251 PG_RETURN_FLOAT8(Sxx / N);
3252}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8_var_samp()

Datum float8_var_samp ( PG_FUNCTION_ARGS  )

Definition at line 3255 of file float.c.

3256{
3259 float8 N,
3260 Sxx;
3261
3262 transvalues = check_float8_array(transarray, "float8_var_samp", 3);
3263 N = transvalues[0];
3264 /* ignore Sx */
3265 Sxx = transvalues[2];
3266
3267 /* Sample variance is undefined when N is 0 or 1, so return NULL */
3268 if (N <= 1.0)
3270
3271 /* Note that Sxx is guaranteed to be non-negative */
3272
3273 PG_RETURN_FLOAT8(Sxx / (N - 1.0));
3274}

References check_float8_array(), fb(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_FLOAT8, and PG_RETURN_NULL.

◆ float8abs()

Datum float8abs ( PG_FUNCTION_ARGS  )

Definition at line 657 of file float.c.

658{
660
662}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8div()

Datum float8div ( PG_FUNCTION_ARGS  )

Definition at line 797 of file float.c.

References fb(), float8_div(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8eq()

Datum float8eq ( PG_FUNCTION_ARGS  )

Definition at line 920 of file float.c.

References fb(), float8_eq(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8ge()

Datum float8ge ( PG_FUNCTION_ARGS  )

Definition at line 965 of file float.c.

References fb(), float8_ge(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8gt()

Datum float8gt ( PG_FUNCTION_ARGS  )

Definition at line 956 of file float.c.

References fb(), float8_gt(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8in()

Datum float8in ( PG_FUNCTION_ARGS  )

Definition at line 364 of file float.c.

365{
366 char *num = PG_GETARG_CSTRING(0);
367
368 PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num,
369 fcinfo->context));
370}
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:395

References fb(), float8in_internal(), PG_GETARG_CSTRING, and PG_RETURN_FLOAT8.

Referenced by numeric_float8().

◆ float8in_internal()

float8 float8in_internal ( char num,
char **  endptr_p,
const char type_name,
const char orig_string,
struct Node escontext 
)

Definition at line 395 of file float.c.

398{
399 double val;
400 char *endptr;
401
402 /* skip leading whitespace */
403 while (*num != '\0' && isspace((unsigned char) *num))
404 num++;
405
406 /*
407 * Check for an empty-string input to begin with, to avoid the vagaries of
408 * strtod() on different platforms.
409 */
410 if (*num == '\0')
411 ereturn(escontext, 0,
413 errmsg("invalid input syntax for type %s: \"%s\"",
414 type_name, orig_string)));
415
416 errno = 0;
417 val = strtod(num, &endptr);
418
419 /* did we not see anything that looks like a double? */
420 if (endptr == num || errno != 0)
421 {
422 int save_errno = errno;
423
424 /*
425 * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
426 * but not all platforms support all of these (and some accept them
427 * but set ERANGE anyway...) Therefore, we check for these inputs
428 * ourselves if strtod() fails.
429 *
430 * Note: C99 also requires hexadecimal input as well as some extended
431 * forms of NaN, but we consider these forms unportable and don't try
432 * to support them. You can use 'em if your strtod() takes 'em.
433 */
434 if (pg_strncasecmp(num, "NaN", 3) == 0)
435 {
437 endptr = num + 3;
438 }
439 else if (pg_strncasecmp(num, "Infinity", 8) == 0)
440 {
442 endptr = num + 8;
443 }
444 else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
445 {
447 endptr = num + 9;
448 }
449 else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
450 {
452 endptr = num + 9;
453 }
454 else if (pg_strncasecmp(num, "inf", 3) == 0)
455 {
457 endptr = num + 3;
458 }
459 else if (pg_strncasecmp(num, "+inf", 4) == 0)
460 {
462 endptr = num + 4;
463 }
464 else if (pg_strncasecmp(num, "-inf", 4) == 0)
465 {
467 endptr = num + 4;
468 }
469 else if (save_errno == ERANGE)
470 {
471 /*
472 * Some platforms return ERANGE for denormalized numbers (those
473 * that are not zero, but are too close to zero to have full
474 * precision). We'd prefer not to throw error for that, so try to
475 * detect whether it's a "real" out-of-range condition by checking
476 * to see if the result is zero or huge.
477 *
478 * On error, we intentionally complain about double precision not
479 * the given type name, and we print only the part of the string
480 * that is the current number.
481 */
482 if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL)
483 {
484 char *errnumber = pstrdup(num);
485
486 errnumber[endptr - num] = '\0';
487 ereturn(escontext, 0,
489 errmsg("\"%s\" is out of range for type double precision",
490 errnumber)));
491 }
492 }
493 else
494 ereturn(escontext, 0,
496 errmsg("invalid input syntax for type %s: \"%s\"",
497 type_name, orig_string)));
498 }
499
500 /* skip trailing whitespace */
501 while (*endptr != '\0' && isspace((unsigned char) *endptr))
502 endptr++;
503
504 /* report stopping point if wanted, else complain if not end of string */
505 if (endptr_p)
506 *endptr_p = endptr;
507 else if (*endptr != '\0')
508 ereturn(escontext, 0,
510 errmsg("invalid input syntax for type %s: \"%s\"",
511 type_name, orig_string)));
512
513 return val;
514}

References ereturn, errcode(), errmsg(), fb(), get_float8_infinity(), get_float8_nan(), pg_strncasecmp(), pstrdup(), and val.

Referenced by dependencies_scalar(), executeItemOptUnwrapTarget(), float8in(), and single_decode().

◆ float8larger()

Datum float8larger ( PG_FUNCTION_ARGS  )

Definition at line 687 of file float.c.

688{
691 float8 result;
692
693 if (float8_gt(arg1, arg2))
694 result = arg1;
695 else
696 result = arg2;
697 PG_RETURN_FLOAT8(result);
698}

References fb(), float8_gt(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8le()

Datum float8le ( PG_FUNCTION_ARGS  )

Definition at line 947 of file float.c.

References fb(), float8_le(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8lt()

Datum float8lt ( PG_FUNCTION_ARGS  )

Definition at line 938 of file float.c.

References fb(), float8_lt(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8mi()

Datum float8mi ( PG_FUNCTION_ARGS  )

Definition at line 779 of file float.c.

References fb(), float8_mi(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8mul()

Datum float8mul ( PG_FUNCTION_ARGS  )

Definition at line 788 of file float.c.

References fb(), float8_mul(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8ne()

Datum float8ne ( PG_FUNCTION_ARGS  )

Definition at line 929 of file float.c.

References fb(), float8_ne(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8out()

Datum float8out ( PG_FUNCTION_ARGS  )

Definition at line 522 of file float.c.

523{
524 float8 num = PG_GETARG_FLOAT8(0);
525
527}
char * float8out_internal(double num)
Definition float.c:537

References float8out_internal(), PG_GETARG_FLOAT8, and PG_RETURN_CSTRING.

◆ float8out_internal()

char * float8out_internal ( double  num)

Definition at line 537 of file float.c.

538{
539 char *ascii = (char *) palloc(32);
541
542 if (extra_float_digits > 0)
543 {
545 return ascii;
546 }
547
548 (void) pg_strfromd(ascii, 32, ndig, num);
549 return ascii;
550}
int double_to_shortest_decimal_buf(double f, char *result)
Definition d2s.c:1053

References ascii(), double_to_shortest_decimal_buf(), extra_float_digits, fb(), palloc(), and pg_strfromd().

Referenced by cube_out(), float8out(), line_out(), pair_encode(), and single_encode().

◆ float8pl()

Datum float8pl ( PG_FUNCTION_ARGS  )

Definition at line 770 of file float.c.

References fb(), float8_pl(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8recv()

Datum float8recv ( PG_FUNCTION_ARGS  )

Definition at line 556 of file float.c.

557{
559
561}
float8 pq_getmsgfloat8(StringInfo msg)
Definition pqformat.c:487

References buf, PG_GETARG_POINTER, PG_RETURN_FLOAT8, and pq_getmsgfloat8().

◆ float8send()

Datum float8send ( PG_FUNCTION_ARGS  )

Definition at line 567 of file float.c.

568{
569 float8 num = PG_GETARG_FLOAT8(0);
571
573 pq_sendfloat8(&buf, num);
575}
void pq_sendfloat8(StringInfo buf, float8 f)
Definition pqformat.c:276

References buf, PG_GETARG_FLOAT8, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), and pq_sendfloat8().

◆ float8smaller()

Datum float8smaller ( PG_FUNCTION_ARGS  )

Definition at line 701 of file float.c.

702{
705 float8 result;
706
707 if (float8_lt(arg1, arg2))
708 result = arg1;
709 else
710 result = arg2;
711 PG_RETURN_FLOAT8(result);
712}

References fb(), float8_lt(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8um()

Datum float8um ( PG_FUNCTION_ARGS  )

Definition at line 669 of file float.c.

670{
672 float8 result;
673
674 result = -arg1;
675 PG_RETURN_FLOAT8(result);
676}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8up()

Datum float8up ( PG_FUNCTION_ARGS  )

Definition at line 679 of file float.c.

680{
682
684}

References arg, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float_overflow_error()

◆ float_underflow_error()

pg_noinline void float_underflow_error ( void  )

Definition at line 94 of file float.c.

95{
98 errmsg("value out of range: underflow")));
99}

References ereport, errcode(), errmsg(), ERROR, and fb().

Referenced by dcbrt(), dcosh(), dexp(), dgamma(), dlog1(), dlog10(), dpow(), dsqrt(), dtof(), float4_div(), float4_mul(), float8_div(), and float8_mul().

◆ float_zero_divide_error()

pg_noinline void float_zero_divide_error ( void  )

Definition at line 102 of file float.c.

103{
106 errmsg("division by zero")));
107}

References ereport, errcode(), errmsg(), ERROR, and fb().

Referenced by float4_div(), and float8_div().

◆ ftod()

Datum ftod ( PG_FUNCTION_ARGS  )

Definition at line 1183 of file float.c.

1184{
1185 float4 num = PG_GETARG_FLOAT4(0);
1186
1187 PG_RETURN_FLOAT8((float8) num);
1188}

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT8.

◆ ftoi2()

Datum ftoi2 ( PG_FUNCTION_ARGS  )

Definition at line 1313 of file float.c.

1314{
1315 float4 num = PG_GETARG_FLOAT4(0);
1316
1317 /*
1318 * Get rid of any fractional part in the input. This is so we don't fail
1319 * on just-out-of-range values that would round into range. Note
1320 * assumption that rint() will pass through a NaN or Inf unchanged.
1321 */
1322 num = rint(num);
1323
1324 /* Range check */
1325 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT16(num)))
1326 ereport(ERROR,
1328 errmsg("smallint out of range")));
1329
1330 PG_RETURN_INT16((int16) num);
1331}
#define FLOAT4_FITS_IN_INT16(num)
Definition c.h:1097

References ereport, errcode(), errmsg(), ERROR, fb(), FLOAT4_FITS_IN_INT16, PG_GETARG_FLOAT4, PG_RETURN_INT16, and unlikely.

◆ ftoi4()

Datum ftoi4 ( PG_FUNCTION_ARGS  )

Definition at line 1288 of file float.c.

1289{
1290 float4 num = PG_GETARG_FLOAT4(0);
1291
1292 /*
1293 * Get rid of any fractional part in the input. This is so we don't fail
1294 * on just-out-of-range values that would round into range. Note
1295 * assumption that rint() will pass through a NaN or Inf unchanged.
1296 */
1297 num = rint(num);
1298
1299 /* Range check */
1300 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT32(num)))
1301 ereport(ERROR,
1303 errmsg("integer out of range")));
1304
1305 PG_RETURN_INT32((int32) num);
1306}
#define FLOAT4_FITS_IN_INT32(num)
Definition c.h:1099

References ereport, errcode(), errmsg(), ERROR, fb(), FLOAT4_FITS_IN_INT32, PG_GETARG_FLOAT4, PG_RETURN_INT32, and unlikely.

◆ i2tod()

Datum i2tod ( PG_FUNCTION_ARGS  )

Definition at line 1276 of file float.c.

1277{
1278 int16 num = PG_GETARG_INT16(0);
1279
1280 PG_RETURN_FLOAT8((float8) num);
1281}
#define PG_GETARG_INT16(n)
Definition fmgr.h:271

References PG_GETARG_INT16, and PG_RETURN_FLOAT8.

◆ i2tof()

Datum i2tof ( PG_FUNCTION_ARGS  )

Definition at line 1350 of file float.c.

1351{
1352 int16 num = PG_GETARG_INT16(0);
1353
1354 PG_RETURN_FLOAT4((float4) num);
1355}

References PG_GETARG_INT16, and PG_RETURN_FLOAT4.

◆ i4tod()

Datum i4tod ( PG_FUNCTION_ARGS  )

Definition at line 1264 of file float.c.

1265{
1266 int32 num = PG_GETARG_INT32(0);
1267
1268 PG_RETURN_FLOAT8((float8) num);
1269}
#define PG_GETARG_INT32(n)
Definition fmgr.h:269

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

◆ i4tof()

Datum i4tof ( PG_FUNCTION_ARGS  )

Definition at line 1338 of file float.c.

1339{
1340 int32 num = PG_GETARG_INT32(0);
1341
1342 PG_RETURN_FLOAT4((float4) num);
1343}

References PG_GETARG_INT32, and PG_RETURN_FLOAT4.

◆ in_range_float4_float8()

Datum in_range_float4_float8 ( PG_FUNCTION_ARGS  )

Definition at line 1103 of file float.c.

1104{
1106 float4 base = PG_GETARG_FLOAT4(1);
1107 float8 offset = PG_GETARG_FLOAT8(2);
1108 bool sub = PG_GETARG_BOOL(3);
1109 bool less = PG_GETARG_BOOL(4);
1110 float8 sum;
1111
1112 /*
1113 * Reject negative or NaN offset. Negative is per spec, and NaN is
1114 * because appropriate semantics for that seem non-obvious.
1115 */
1116 if (isnan(offset) || offset < 0)
1117 ereport(ERROR,
1119 errmsg("invalid preceding or following size in window function")));
1120
1121 /*
1122 * Deal with cases where val and/or base is NaN, following the rule that
1123 * NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1124 * affect the conclusion.
1125 */
1126 if (isnan(val))
1127 {
1128 if (isnan(base))
1129 PG_RETURN_BOOL(true); /* NAN = NAN */
1130 else
1131 PG_RETURN_BOOL(!less); /* NAN > non-NAN */
1132 }
1133 else if (isnan(base))
1134 {
1135 PG_RETURN_BOOL(less); /* non-NAN < NAN */
1136 }
1137
1138 /*
1139 * Deal with cases where both base and offset are infinite, and computing
1140 * base +/- offset would produce NaN. This corresponds to a window frame
1141 * whose boundary infinitely precedes +inf or infinitely follows -inf,
1142 * which is not well-defined. For consistency with other cases involving
1143 * infinities, such as the fact that +inf infinitely follows +inf, we
1144 * choose to assume that +inf infinitely precedes +inf and -inf infinitely
1145 * follows -inf, and therefore that all finite and infinite values are in
1146 * such a window frame.
1147 *
1148 * offset is known positive, so we need only check the sign of base in
1149 * this test.
1150 */
1151 if (isinf(offset) && isinf(base) &&
1152 (sub ? base > 0 : base < 0))
1154
1155 /*
1156 * Otherwise it should be safe to compute base +/- offset. We trust the
1157 * FPU to cope if an input is +/-inf or the true sum would overflow, and
1158 * produce a suitably signed infinity, which will compare properly against
1159 * val whether or not that's infinity.
1160 */
1161 if (sub)
1162 sum = base - offset;
1163 else
1164 sum = base + offset;
1165
1166 if (less)
1167 PG_RETURN_BOOL(val <= sum);
1168 else
1169 PG_RETURN_BOOL(val >= sum);
1170}
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
return true
Definition isn.c:130

References ereport, errcode(), errmsg(), ERROR, fb(), PG_GETARG_BOOL, PG_GETARG_FLOAT4, PG_GETARG_FLOAT8, PG_RETURN_BOOL, and val.

◆ in_range_float8_float8()

Datum in_range_float8_float8 ( PG_FUNCTION_ARGS  )

Definition at line 1027 of file float.c.

1028{
1030 float8 base = PG_GETARG_FLOAT8(1);
1031 float8 offset = PG_GETARG_FLOAT8(2);
1032 bool sub = PG_GETARG_BOOL(3);
1033 bool less = PG_GETARG_BOOL(4);
1034 float8 sum;
1035
1036 /*
1037 * Reject negative or NaN offset. Negative is per spec, and NaN is
1038 * because appropriate semantics for that seem non-obvious.
1039 */
1040 if (isnan(offset) || offset < 0)
1041 ereport(ERROR,
1043 errmsg("invalid preceding or following size in window function")));
1044
1045 /*
1046 * Deal with cases where val and/or base is NaN, following the rule that
1047 * NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1048 * affect the conclusion.
1049 */
1050 if (isnan(val))
1051 {
1052 if (isnan(base))
1053 PG_RETURN_BOOL(true); /* NAN = NAN */
1054 else
1055 PG_RETURN_BOOL(!less); /* NAN > non-NAN */
1056 }
1057 else if (isnan(base))
1058 {
1059 PG_RETURN_BOOL(less); /* non-NAN < NAN */
1060 }
1061
1062 /*
1063 * Deal with cases where both base and offset are infinite, and computing
1064 * base +/- offset would produce NaN. This corresponds to a window frame
1065 * whose boundary infinitely precedes +inf or infinitely follows -inf,
1066 * which is not well-defined. For consistency with other cases involving
1067 * infinities, such as the fact that +inf infinitely follows +inf, we
1068 * choose to assume that +inf infinitely precedes +inf and -inf infinitely
1069 * follows -inf, and therefore that all finite and infinite values are in
1070 * such a window frame.
1071 *
1072 * offset is known positive, so we need only check the sign of base in
1073 * this test.
1074 */
1075 if (isinf(offset) && isinf(base) &&
1076 (sub ? base > 0 : base < 0))
1078
1079 /*
1080 * Otherwise it should be safe to compute base +/- offset. We trust the
1081 * FPU to cope if an input is +/-inf or the true sum would overflow, and
1082 * produce a suitably signed infinity, which will compare properly against
1083 * val whether or not that's infinity.
1084 */
1085 if (sub)
1086 sum = base - offset;
1087 else
1088 sum = base + offset;
1089
1090 if (less)
1091 PG_RETURN_BOOL(val <= sum);
1092 else
1093 PG_RETURN_BOOL(val >= sum);
1094}

References ereport, errcode(), errmsg(), ERROR, fb(), PG_GETARG_BOOL, PG_GETARG_FLOAT8, PG_RETURN_BOOL, and val.

◆ init_degree_constants()

static void init_degree_constants ( void  )
static

◆ is_infinite()

int is_infinite ( double  val)

Definition at line 118 of file float.c.

119{
120 int inf = isinf(val);
121
122 if (inf == 0)
123 return 0;
124 else if (val > 0)
125 return 1;
126 else
127 return -1;
128}

References fb(), and val.

◆ radians()

Datum radians ( PG_FUNCTION_ARGS  )

◆ sind_0_to_30()

static double sind_0_to_30 ( double  x)
static

Definition at line 2252 of file float.c.

2253{
2254 volatile float8 sin_x = sin(x * RADIANS_PER_DEGREE);
2255
2256 return (sin_x / sin_30) / 2.0;
2257}

References fb(), RADIANS_PER_DEGREE, sin_30, and x.

Referenced by cosd_q1(), and sind_q1().

◆ sind_q1()

static double sind_q1 ( double  x)
static

Definition at line 2279 of file float.c.

2280{
2281 /*
2282 * Stitch together the sine and cosine functions for the ranges [0, 30]
2283 * and (30, 90]. These guarantee to return exact answers at their
2284 * endpoints, so the overall result is a continuous monotonic function
2285 * that gives exact results when x = 0, 30 and 90 degrees.
2286 */
2287 if (x <= 30.0)
2288 return sind_0_to_30(x);
2289 else
2290 return cosd_0_to_60(90.0 - x);
2291}

References cosd_0_to_60(), sind_0_to_30(), and x.

Referenced by dcotd(), dsind(), dtand(), and init_degree_constants().

◆ width_bucket_float8()

Datum width_bucket_float8 ( PG_FUNCTION_ARGS  )

Definition at line 4188 of file float.c.

4189{
4190 float8 operand = PG_GETARG_FLOAT8(0);
4193 int32 count = PG_GETARG_INT32(3);
4194 int32 result;
4195
4196 if (count <= 0)
4197 ereport(ERROR,
4199 errmsg("count must be greater than zero")));
4200
4201 if (isnan(bound1) || isnan(bound2))
4202 ereport(ERROR,
4204 errmsg("lower and upper bounds cannot be NaN")));
4205
4206 if (isinf(bound1) || isinf(bound2))
4207 ereport(ERROR,
4209 errmsg("lower and upper bounds must be finite")));
4210
4211 if (bound1 < bound2)
4212 {
4213 if (isnan(operand) || operand >= bound2)
4214 {
4215 if (pg_add_s32_overflow(count, 1, &result))
4216 ereport(ERROR,
4218 errmsg("integer out of range")));
4219 }
4220 else if (operand < bound1)
4221 result = 0;
4222 else
4223 {
4224 if (!isinf(bound2 - bound1))
4225 {
4226 /* The quotient is surely in [0,1], so this can't overflow */
4227 result = count * ((operand - bound1) / (bound2 - bound1));
4228 }
4229 else
4230 {
4231 /*
4232 * We get here if bound2 - bound1 overflows DBL_MAX. Since
4233 * both bounds are finite, their difference can't exceed twice
4234 * DBL_MAX; so we can perform the computation without overflow
4235 * by dividing all the inputs by 2. That should be exact too,
4236 * except in the case where a very small operand underflows to
4237 * zero, which would have negligible impact on the result
4238 * given such large bounds.
4239 */
4240 result = count * ((operand / 2 - bound1 / 2) / (bound2 / 2 - bound1 / 2));
4241 }
4242 /* The quotient could round to 1.0, which would be a lie */
4243 if (result >= count)
4244 result = count - 1;
4245 /* Having done that, we can add 1 without fear of overflow */
4246 result++;
4247 }
4248 }
4249 else if (bound1 > bound2)
4250 {
4251 if (isnan(operand) || operand > bound1)
4252 result = 0;
4253 else if (operand <= bound2)
4254 {
4255 if (pg_add_s32_overflow(count, 1, &result))
4256 ereport(ERROR,
4258 errmsg("integer out of range")));
4259 }
4260 else
4261 {
4262 if (!isinf(bound1 - bound2))
4263 result = count * ((bound1 - operand) / (bound1 - bound2));
4264 else
4265 result = count * ((bound1 / 2 - operand / 2) / (bound1 / 2 - bound2 / 2));
4266 if (result >= count)
4267 result = count - 1;
4268 result++;
4269 }
4270 }
4271 else
4272 {
4273 ereport(ERROR,
4275 errmsg("lower bound cannot equal upper bound")));
4276 result = 0; /* keep the compiler quiet */
4277 }
4278
4279 PG_RETURN_INT32(result);
4280}
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:151

References ereport, errcode(), errmsg(), ERROR, fb(), pg_add_s32_overflow(), PG_GETARG_FLOAT8, PG_GETARG_INT32, and PG_RETURN_INT32.

Variable Documentation

◆ acos_0_5

float8 acos_0_5 = 0
static

Definition at line 47 of file float.c.

Referenced by acosd_q1(), asind_q1(), and init_degree_constants().

◆ asin_0_5

float8 asin_0_5 = 0
static

Definition at line 46 of file float.c.

Referenced by acosd_q1(), asind_q1(), and init_degree_constants().

◆ atan_1_0

float8 atan_1_0 = 0
static

Definition at line 48 of file float.c.

Referenced by datan2d(), datand(), and init_degree_constants().

◆ cot_45

float8 cot_45 = 0
static

Definition at line 50 of file float.c.

Referenced by dcotd(), and init_degree_constants().

◆ degree_c_forty_five

float8 degree_c_forty_five = 45.0

Definition at line 67 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_one

float8 degree_c_one = 1.0

Definition at line 70 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_one_half

float8 degree_c_one_half = 0.5

Definition at line 69 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_sixty

float8 degree_c_sixty = 60.0

Definition at line 68 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_thirty

float8 degree_c_thirty = 30.0

Definition at line 66 of file float.c.

Referenced by init_degree_constants().

◆ degree_consts_set

bool degree_consts_set = false
static

Definition at line 43 of file float.c.

Referenced by init_degree_constants().

◆ extra_float_digits

int extra_float_digits = 1

Definition at line 40 of file float.c.

Referenced by float4out(), float8out_internal(), and set_transmission_modes().

◆ one_minus_cos_60

float8 one_minus_cos_60 = 0
static

Definition at line 45 of file float.c.

Referenced by cosd_0_to_60(), and init_degree_constants().

◆ sin_30

float8 sin_30 = 0
static

Definition at line 44 of file float.c.

Referenced by init_degree_constants(), and sind_0_to_30().

◆ tan_45

float8 tan_45 = 0
static

Definition at line 49 of file float.c.

Referenced by dtand(), and init_degree_constants().