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:60
static int fb(int x)

Definition at line 2048 of file float.c.

2049 { \
2052} while(0)

Function Documentation

◆ acosd_q1()

static double acosd_q1 ( double  x)
static

Definition at line 2098 of file float.c.

2099{
2100 /*
2101 * Stitch together inverse sine and cosine functions for the ranges [0,
2102 * 0.5] and (0.5, 1]. Each expression below is guaranteed to return
2103 * exactly 60 for x=0.5, so the result is a continuous monotonic function
2104 * over the full range.
2105 */
2106 if (x <= 0.5)
2107 {
2108 volatile float8 asin_x = asin(x);
2109
2110 return 90.0 - (asin_x / asin_0_5) * 30.0;
2111 }
2112 else
2113 {
2114 volatile float8 acos_x = acos(x);
2115
2116 return (acos_x / acos_0_5) * 60.0;
2117 }
2118}
double float8
Definition c.h:716
static float8 acos_0_5
Definition float.c:64
static float8 asin_0_5
Definition float.c:63
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 2065 of file float.c.

2066{
2067 /*
2068 * Stitch together inverse sine and cosine functions for the ranges [0,
2069 * 0.5] and (0.5, 1]. Each expression below is guaranteed to return
2070 * exactly 30 for x=0.5, so the result is a continuous monotonic function
2071 * over the full range.
2072 */
2073 if (x <= 0.5)
2074 {
2075 volatile float8 asin_x = asin(x);
2076
2077 return (asin_x / asin_0_5) * 30.0;
2078 }
2079 else
2080 {
2081 volatile float8 acos_x = acos(x);
2082
2083 return 90.0 - (acos_x / acos_0_5) * 60.0;
2084 }
2085}

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

Referenced by dacosd(), and dasind().

◆ btfloat48cmp()

Datum btfloat48cmp ( PG_FUNCTION_ARGS  )

Definition at line 1018 of file float.c.

1019{
1022
1023 /* widen float4 to float8 and then compare */
1025}
float float4
Definition c.h:715
int float8_cmp_internal(float8 a, float8 b)
Definition float.c:927
#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 897 of file float.c.

898{
901
903}
int float4_cmp_internal(float4 a, float4 b)
Definition float.c:833

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 906 of file float.c.

907{
910
912}
int y
Definition isn.c:76
static float4 DatumGetFloat4(Datum X)
Definition postgres.h:451

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

Referenced by btfloat4sortsupport().

◆ btfloat4sortsupport()

Datum btfloat4sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 915 of file float.c.

916{
918
921}
struct SortSupportData * SortSupport
Definition execnodes.h:60
static int btfloat4fastcmp(Datum x, Datum y, SortSupport ssup)
Definition float.c:906
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
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 1028 of file float.c.

1029{
1032
1033 /* widen float4 to float8 and then compare */
1035}

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 1000 of file float.c.

1001{
1004
1005 return float8_cmp_internal(arg1, arg2);
1006}
static float8 DatumGetFloat8(Datum X)
Definition postgres.h:485

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

Referenced by btfloat8sortsupport().

◆ btfloat8sortsupport()

Datum btfloat8sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 1009 of file float.c.

1010{
1012
1015}
static int btfloat8fastcmp(Datum x, Datum y, SortSupport ssup)
Definition float.c:1000

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 2950 of file float.c.

2951{
2952 /*
2953 * We expect the input to be an N-element float array; verify that. We
2954 * don't need to use deconstruct_array() since the array data is just
2955 * going to look like a C array of N float8 values.
2956 */
2957 if (ARR_NDIM(transarray) != 1 ||
2958 ARR_DIMS(transarray)[0] != n ||
2961 elog(ERROR, "%s: expected %d-element float8 array", caller, n);
2962 return (float8 *) ARR_DATA_PTR(transarray);
2963}
#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 2283 of file float.c.

2284{
2285 volatile float8 one_minus_cos_x = 1.0 - cos(x * RADIANS_PER_DEGREE);
2286
2287 return 1.0 - (one_minus_cos_x / one_minus_cos_60) / 2.0;
2288}
static float8 one_minus_cos_60
Definition float.c:62
#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 2316 of file float.c.

2317{
2318 /*
2319 * Stitch together the sine and cosine functions for the ranges [0, 60]
2320 * and (60, 90]. These guarantee to return exact answers at their
2321 * endpoints, so the overall result is a continuous monotonic function
2322 * that gives exact results when x = 0, 60 and 90 degrees.
2323 */
2324 if (x <= 60.0)
2325 return cosd_0_to_60(x);
2326 else
2327 return sind_0_to_30(90.0 - x);
2328}
static double sind_0_to_30(double x)
Definition float.c:2269
static double cosd_0_to_60(double x)
Definition float.c:2283

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 1772 of file float.c.

1773{
1775 float8 result;
1776
1777 /* Per the POSIX spec, return NaN if the input is NaN */
1778 if (isnan(arg1))
1780
1781 /*
1782 * The principal branch of the inverse cosine function maps values in the
1783 * range [-1, 1] to values in the range [0, Pi], so we should reject any
1784 * inputs outside that range and the result will always be finite.
1785 */
1786 if (arg1 < -1.0 || arg1 > 1.0)
1787 ereport(ERROR,
1789 errmsg("input is out of range")));
1790
1791 result = acos(arg1);
1792 if (unlikely(isinf(result)))
1794
1795 PG_RETURN_FLOAT8(result);
1796}
#define unlikely(x)
Definition c.h:432
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereport(elevel,...)
Definition elog.h:150
pg_noinline void float_overflow_error(void)
Definition float.c:103
static float8 get_float8_nan(void)
Definition float.h:84
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
static char * errmsg

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 2125 of file float.c.

2126{
2128 float8 result;
2129
2130 /* Per the POSIX spec, return NaN if the input is NaN */
2131 if (isnan(arg1))
2133
2135
2136 /*
2137 * The principal branch of the inverse cosine function maps values in the
2138 * range [-1, 1] to values in the range [0, 180], so we should reject any
2139 * inputs outside that range and the result will always be finite.
2140 */
2141 if (arg1 < -1.0 || arg1 > 1.0)
2142 ereport(ERROR,
2144 errmsg("input is out of range")));
2145
2146 if (arg1 >= 0.0)
2147 result = acosd_q1(arg1);
2148 else
2149 result = 90.0 + asind_q1(-arg1);
2150
2151 if (unlikely(isinf(result)))
2153
2154 PG_RETURN_FLOAT8(result);
2155}
static double acosd_q1(double x)
Definition float.c:2098
static double asind_q1(double x)
Definition float.c:2065
#define INIT_DEGREE_CONSTANTS()
Definition float.c:2048

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 2706 of file float.c.

2707{
2709 float8 result;
2710
2711 /*
2712 * acosh is only defined for inputs >= 1.0. By checking this ourselves,
2713 * we need not worry about checking for an EDOM error, which is a good
2714 * thing because some implementations will report that for NaN. Otherwise,
2715 * no error is possible.
2716 */
2717 if (arg1 < 1.0)
2718 ereport(ERROR,
2720 errmsg("input is out of range")));
2721
2722 result = acosh(arg1);
2723
2724 PG_RETURN_FLOAT8(result);
2725}

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

◆ dasin()

Datum dasin ( PG_FUNCTION_ARGS  )

Definition at line 1803 of file float.c.

1804{
1806 float8 result;
1807
1808 /* Per the POSIX spec, return NaN if the input is NaN */
1809 if (isnan(arg1))
1811
1812 /*
1813 * The principal branch of the inverse sine function maps values in the
1814 * range [-1, 1] to values in the range [-Pi/2, Pi/2], so we should reject
1815 * any inputs outside that range and the result will always be finite.
1816 */
1817 if (arg1 < -1.0 || arg1 > 1.0)
1818 ereport(ERROR,
1820 errmsg("input is out of range")));
1821
1822 result = asin(arg1);
1823 if (unlikely(isinf(result)))
1825
1826 PG_RETURN_FLOAT8(result);
1827}

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 2162 of file float.c.

2163{
2165 float8 result;
2166
2167 /* Per the POSIX spec, return NaN if the input is NaN */
2168 if (isnan(arg1))
2170
2172
2173 /*
2174 * The principal branch of the inverse sine function maps values in the
2175 * range [-1, 1] to values in the range [-90, 90], so we should reject any
2176 * inputs outside that range and the result will always be finite.
2177 */
2178 if (arg1 < -1.0 || arg1 > 1.0)
2179 ereport(ERROR,
2181 errmsg("input is out of range")));
2182
2183 if (arg1 >= 0.0)
2184 result = asind_q1(arg1);
2185 else
2186 result = -asind_q1(-arg1);
2187
2188 if (unlikely(isinf(result)))
2190
2191 PG_RETURN_FLOAT8(result);
2192}

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 2689 of file float.c.

2690{
2692 float8 result;
2693
2694 /*
2695 * For asinh, we don't need an errno check because it never overflows.
2696 */
2697 result = asinh(arg1);
2698
2699 PG_RETURN_FLOAT8(result);
2700}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ datan()

Datum datan ( PG_FUNCTION_ARGS  )

Definition at line 1834 of file float.c.

1835{
1837 float8 result;
1838
1839 /* Per the POSIX spec, return NaN if the input is NaN */
1840 if (isnan(arg1))
1842
1843 /*
1844 * The principal branch of the inverse tangent function maps all inputs to
1845 * values in the range [-Pi/2, Pi/2], so the result should always be
1846 * finite, even if the input is infinite.
1847 */
1848 result = atan(arg1);
1849 if (unlikely(isinf(result)))
1851
1852 PG_RETURN_FLOAT8(result);
1853}

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 1860 of file float.c.

1861{
1864 float8 result;
1865
1866 /* Per the POSIX spec, return NaN if either input is NaN */
1867 if (isnan(arg1) || isnan(arg2))
1869
1870 /*
1871 * atan2 maps all inputs to values in the range [-Pi, Pi], so the result
1872 * should always be finite, even if the inputs are infinite.
1873 */
1874 result = atan2(arg1, arg2);
1875 if (unlikely(isinf(result)))
1877
1878 PG_RETURN_FLOAT8(result);
1879}

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 2231 of file float.c.

2232{
2235 float8 result;
2236 volatile float8 atan2_arg1_arg2;
2237
2238 /* Per the POSIX spec, return NaN if either input is NaN */
2239 if (isnan(arg1) || isnan(arg2))
2241
2243
2244 /*
2245 * atan2d maps all inputs to values in the range [-180, 180], so the
2246 * result should always be finite, even if the inputs are infinite.
2247 *
2248 * Note: this coding assumes that atan(1.0) is a suitable scaling constant
2249 * to get an exact result from atan2(). This might well fail on us at
2250 * some point, requiring us to decide exactly what inputs we think we're
2251 * going to guarantee an exact result for.
2252 */
2254 result = (atan2_arg1_arg2 / atan_1_0) * 45.0;
2255
2256 if (unlikely(isinf(result)))
2258
2259 PG_RETURN_FLOAT8(result);
2260}
static float8 atan_1_0
Definition float.c:65

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 2199 of file float.c.

2200{
2202 float8 result;
2203 volatile float8 atan_arg1;
2204
2205 /* Per the POSIX spec, return NaN if the input is NaN */
2206 if (isnan(arg1))
2208
2210
2211 /*
2212 * The principal branch of the inverse tangent function maps all inputs to
2213 * values in the range [-90, 90], so the result should always be finite,
2214 * even if the input is infinite. Additionally, we take care to ensure
2215 * than when arg1 is 1, the result is exactly 45.
2216 */
2217 atan_arg1 = atan(arg1);
2218 result = (atan_arg1 / atan_1_0) * 45.0;
2219
2220 if (unlikely(isinf(result)))
2222
2223 PG_RETURN_FLOAT8(result);
2224}

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 2731 of file float.c.

2732{
2734 float8 result;
2735
2736 /*
2737 * atanh is only defined for inputs between -1 and 1. By checking this
2738 * ourselves, we need not worry about checking for an EDOM error, which is
2739 * a good thing because some implementations will report that for NaN.
2740 */
2741 if (arg1 < -1.0 || arg1 > 1.0)
2742 ereport(ERROR,
2744 errmsg("input is out of range")));
2745
2746 /*
2747 * Also handle the infinity cases ourselves; this is helpful because old
2748 * glibc versions may produce the wrong errno for this. All other inputs
2749 * cannot produce an error.
2750 */
2751 if (arg1 == -1.0)
2752 result = -get_float8_infinity();
2753 else if (arg1 == 1.0)
2754 result = get_float8_infinity();
2755 else
2756 result = atanh(arg1);
2757
2758 PG_RETURN_FLOAT8(result);
2759}
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 1487 of file float.c.

1488{
1490 float8 result;
1491
1492 result = cbrt(arg1);
1493 if (unlikely(isinf(result)) && !isinf(arg1))
1495 if (unlikely(result == 0.0) && arg1 != 0.0)
1497
1498 PG_RETURN_FLOAT8(result);
1499}
pg_noinline void float_underflow_error(void)
Definition float.c:111

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 1397 of file float.c.

1398{
1400
1402}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dcos()

Datum dcos ( PG_FUNCTION_ARGS  )

Definition at line 1886 of file float.c.

1887{
1889 float8 result;
1890
1891 /* Per the POSIX spec, return NaN if the input is NaN */
1892 if (isnan(arg1))
1894
1895 /*
1896 * cos() is periodic and so theoretically can work for all finite inputs,
1897 * but some implementations may choose to throw error if the input is so
1898 * large that there are no significant digits in the result. So we should
1899 * check for errors. POSIX allows an error to be reported either via
1900 * errno or via fetestexcept(), but currently we only support checking
1901 * errno. (fetestexcept() is rumored to report underflow unreasonably
1902 * early on some platforms, so it's not clear that believing it would be a
1903 * net improvement anyway.)
1904 *
1905 * For infinite inputs, POSIX specifies that the trigonometric functions
1906 * should return a domain error; but we won't notice that unless the
1907 * platform reports via errno, so also explicitly test for infinite
1908 * inputs.
1909 */
1910 errno = 0;
1911 result = cos(arg1);
1912 if (errno != 0 || isinf(arg1))
1913 ereport(ERROR,
1915 errmsg("input is out of range")));
1916 if (unlikely(isinf(result)))
1918
1919 PG_RETURN_FLOAT8(result);
1920}

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 2335 of file float.c.

2336{
2338 float8 result;
2339 int sign = 1;
2340
2341 /*
2342 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2343 * if the input is infinite.
2344 */
2345 if (isnan(arg1))
2347
2348 if (isinf(arg1))
2349 ereport(ERROR,
2351 errmsg("input is out of range")));
2352
2354
2355 /* Reduce the range of the input to [0,90] degrees */
2356 arg1 = fmod(arg1, 360.0);
2357
2358 if (arg1 < 0.0)
2359 {
2360 /* cosd(-x) = cosd(x) */
2361 arg1 = -arg1;
2362 }
2363
2364 if (arg1 > 180.0)
2365 {
2366 /* cosd(360-x) = cosd(x) */
2367 arg1 = 360.0 - arg1;
2368 }
2369
2370 if (arg1 > 90.0)
2371 {
2372 /* cosd(180-x) = -cosd(x) */
2373 arg1 = 180.0 - arg1;
2374 sign = -sign;
2375 }
2376
2377 result = sign * cosd_q1(arg1);
2378
2379 if (unlikely(isinf(result)))
2381
2382 PG_RETURN_FLOAT8(result);
2383}
static double cosd_q1(double x)
Definition float.c:2316
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 2644 of file float.c.

2645{
2647 float8 result;
2648
2649 errno = 0;
2650 result = cosh(arg1);
2651
2652 /*
2653 * if an ERANGE error occurs, it means there is an overflow. As cosh is
2654 * always positive, it always means the result is positive infinity.
2655 */
2656 if (errno == ERANGE)
2657 result = get_float8_infinity();
2658
2659 if (unlikely(result == 0.0))
2661
2662 PG_RETURN_FLOAT8(result);
2663}

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 1927 of file float.c.

1928{
1930 float8 result;
1931
1932 /* Per the POSIX spec, return NaN if the input is NaN */
1933 if (isnan(arg1))
1935
1936 /* Be sure to throw an error if the input is infinite --- see dcos() */
1937 errno = 0;
1938 result = tan(arg1);
1939 if (errno != 0 || isinf(arg1))
1940 ereport(ERROR,
1942 errmsg("input is out of range")));
1943
1944 result = 1.0 / result;
1945 /* Not checking for overflow because cot(0) == Inf */
1946
1947 PG_RETURN_FLOAT8(result);
1948}

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 2390 of file float.c.

2391{
2393 float8 result;
2394 volatile float8 cot_arg1;
2395 int sign = 1;
2396
2397 /*
2398 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2399 * if the input is infinite.
2400 */
2401 if (isnan(arg1))
2403
2404 if (isinf(arg1))
2405 ereport(ERROR,
2407 errmsg("input is out of range")));
2408
2410
2411 /* Reduce the range of the input to [0,90] degrees */
2412 arg1 = fmod(arg1, 360.0);
2413
2414 if (arg1 < 0.0)
2415 {
2416 /* cotd(-x) = -cotd(x) */
2417 arg1 = -arg1;
2418 sign = -sign;
2419 }
2420
2421 if (arg1 > 180.0)
2422 {
2423 /* cotd(360-x) = -cotd(x) */
2424 arg1 = 360.0 - arg1;
2425 sign = -sign;
2426 }
2427
2428 if (arg1 > 90.0)
2429 {
2430 /* cotd(180-x) = -cotd(x) */
2431 arg1 = 180.0 - arg1;
2432 sign = -sign;
2433 }
2434
2436 result = sign * (cot_arg1 / cot_45);
2437
2438 /*
2439 * On some machines we get cotd(270) = minus zero, but this isn't always
2440 * true. For portability, and because the user constituency for this
2441 * function probably doesn't want minus zero, force it to plain zero.
2442 */
2443 if (result == 0.0)
2444 result = 0.0;
2445
2446 /* Not checking for overflow because cotd(0) == Inf */
2447
2448 PG_RETURN_FLOAT8(result);
2449}
static float8 cot_45
Definition float.c:67
static double sind_q1(double x)
Definition float.c:2296

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 2578 of file float.c.

2579{
2581
2583}
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 2769 of file float.c.

2770{
2772 float8 result;
2773
2774 /*
2775 * For erf, we don't need an errno check because it never overflows.
2776 */
2777 result = erf(arg1);
2778
2779 if (unlikely(isinf(result)))
2781
2782 PG_RETURN_FLOAT8(result);
2783}

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

◆ derfc()

Datum derfc ( PG_FUNCTION_ARGS  )

Definition at line 2789 of file float.c.

2790{
2792 float8 result;
2793
2794 /*
2795 * For erfc, we don't need an errno check because it never overflows.
2796 */
2797 result = erfc(arg1);
2798
2799 if (unlikely(isinf(result)))
2801
2802 PG_RETURN_FLOAT8(result);
2803}

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

◆ dexp()

Datum dexp ( PG_FUNCTION_ARGS  )

Definition at line 1661 of file float.c.

1662{
1664 float8 result;
1665
1666 /*
1667 * Handle NaN and Inf cases explicitly. This avoids needing to assume
1668 * that the platform's exp() conforms to POSIX for these cases, and it
1669 * removes some edge cases for the overflow checks below.
1670 */
1671 if (isnan(arg1))
1672 result = arg1;
1673 else if (isinf(arg1))
1674 {
1675 /* Per POSIX, exp(-Inf) is 0 */
1676 result = (arg1 > 0.0) ? arg1 : 0;
1677 }
1678 else
1679 {
1680 /*
1681 * On some platforms, exp() will not set errno but just return Inf or
1682 * zero to report overflow/underflow; therefore, test both cases.
1683 */
1684 errno = 0;
1685 result = exp(arg1);
1686 if (unlikely(errno == ERANGE))
1687 {
1688 if (result != 0.0)
1690 else
1692 }
1693 else if (unlikely(isinf(result)))
1695 else if (unlikely(result == 0.0))
1697 }
1698
1699 PG_RETURN_FLOAT8(result);
1700}

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 1409 of file float.c.

1410{
1412
1414}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dgamma()

Datum dgamma ( PG_FUNCTION_ARGS  )

Definition at line 2813 of file float.c.

2814{
2816 float8 result;
2817
2818 /*
2819 * Handle NaN and Inf cases explicitly. This simplifies the overflow
2820 * checks on platforms that do not set errno.
2821 */
2822 if (isnan(arg1))
2823 result = arg1;
2824 else if (isinf(arg1))
2825 {
2826 /* Per POSIX, an input of -Inf causes a domain error */
2827 if (arg1 < 0)
2828 {
2830 result = get_float8_nan(); /* keep compiler quiet */
2831 }
2832 else
2833 result = arg1;
2834 }
2835 else
2836 {
2837 /*
2838 * Note: the POSIX/C99 gamma function is called "tgamma", not "gamma".
2839 *
2840 * On some platforms, tgamma() will not set errno but just return Inf,
2841 * NaN, or zero to report overflow/underflow; therefore, test those
2842 * cases explicitly (note that, like the exponential function, the
2843 * gamma function has no zeros).
2844 */
2845 errno = 0;
2846 result = tgamma(arg1);
2847
2848 if (errno != 0 || isinf(result) || isnan(result))
2849 {
2850 if (result != 0.0)
2852 else
2854 }
2855 else if (result == 0.0)
2857 }
2858
2859 PG_RETURN_FLOAT8(result);
2860}

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 2867 of file float.c.

2868{
2870 float8 result;
2871
2872 /* On some versions of AIX, lgamma(NaN) fails with ERANGE */
2873#if defined(_AIX)
2874 if (isnan(arg1))
2876#endif
2877
2878 /*
2879 * Note: lgamma may not be thread-safe because it may write to a global
2880 * variable signgam, which may not be thread-local. However, this doesn't
2881 * matter to us, since we don't use signgam.
2882 */
2883 errno = 0;
2884 result = lgamma(arg1);
2885
2886 /*
2887 * If an ERANGE error occurs, it means there was an overflow or a pole
2888 * error (which happens for zero and negative integer inputs).
2889 *
2890 * On some platforms, lgamma() will not set errno but just return infinity
2891 * to report overflow, but it should never underflow.
2892 */
2893 if (errno == ERANGE || (isinf(result) && !isinf(arg1)))
2895
2896 PG_RETURN_FLOAT8(result);
2897}

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

◆ dlog1()

Datum dlog1 ( PG_FUNCTION_ARGS  )

Definition at line 1707 of file float.c.

1708{
1710 float8 result;
1711
1712 /*
1713 * Emit particular SQLSTATE error codes for ln(). This is required by the
1714 * SQL standard.
1715 */
1716 if (arg1 == 0.0)
1717 ereport(ERROR,
1719 errmsg("cannot take logarithm of zero")));
1720 if (arg1 < 0)
1721 ereport(ERROR,
1723 errmsg("cannot take logarithm of a negative number")));
1724
1725 result = log(arg1);
1726 if (unlikely(isinf(result)) && !isinf(arg1))
1728 if (unlikely(result == 0.0) && arg1 != 1.0)
1730
1731 PG_RETURN_FLOAT8(result);
1732}

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 1739 of file float.c.

1740{
1742 float8 result;
1743
1744 /*
1745 * Emit particular SQLSTATE error codes for log(). The SQL spec doesn't
1746 * define log(), but it does define ln(), so it makes sense to emit the
1747 * same error code for an analogous error condition.
1748 */
1749 if (arg1 == 0.0)
1750 ereport(ERROR,
1752 errmsg("cannot take logarithm of zero")));
1753 if (arg1 < 0)
1754 ereport(ERROR,
1756 errmsg("cannot take logarithm of a negative number")));
1757
1758 result = log10(arg1);
1759 if (unlikely(isinf(result)) && !isinf(arg1))
1761 if (unlikely(result == 0.0) && arg1 != 1.0)
1763
1764 PG_RETURN_FLOAT8(result);
1765}

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

◆ dpi()

Definition at line 2590 of file float.c.

2591{
2593}
#define M_PI

References M_PI, and PG_RETURN_FLOAT8.

◆ dpow()

Datum dpow ( PG_FUNCTION_ARGS  )

Definition at line 1506 of file float.c.

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

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 1385 of file float.c.

1386{
1388
1390}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsign()

Datum dsign ( PG_FUNCTION_ARGS  )

Definition at line 1422 of file float.c.

1423{
1425 float8 result;
1426
1427 if (arg1 > 0)
1428 result = 1.0;
1429 else if (arg1 < 0)
1430 result = -1.0;
1431 else
1432 result = 0.0;
1433
1434 PG_RETURN_FLOAT8(result);
1435}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsin()

Datum dsin ( PG_FUNCTION_ARGS  )

Definition at line 1955 of file float.c.

1956{
1958 float8 result;
1959
1960 /* Per the POSIX spec, return NaN if the input is NaN */
1961 if (isnan(arg1))
1963
1964 /* Be sure to throw an error if the input is infinite --- see dcos() */
1965 errno = 0;
1966 result = sin(arg1);
1967 if (errno != 0 || isinf(arg1))
1968 ereport(ERROR,
1970 errmsg("input is out of range")));
1971 if (unlikely(isinf(result)))
1973
1974 PG_RETURN_FLOAT8(result);
1975}

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 2456 of file float.c.

2457{
2459 float8 result;
2460 int sign = 1;
2461
2462 /*
2463 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2464 * if the input is infinite.
2465 */
2466 if (isnan(arg1))
2468
2469 if (isinf(arg1))
2470 ereport(ERROR,
2472 errmsg("input is out of range")));
2473
2475
2476 /* Reduce the range of the input to [0,90] degrees */
2477 arg1 = fmod(arg1, 360.0);
2478
2479 if (arg1 < 0.0)
2480 {
2481 /* sind(-x) = -sind(x) */
2482 arg1 = -arg1;
2483 sign = -sign;
2484 }
2485
2486 if (arg1 > 180.0)
2487 {
2488 /* sind(360-x) = -sind(x) */
2489 arg1 = 360.0 - arg1;
2490 sign = -sign;
2491 }
2492
2493 if (arg1 > 90.0)
2494 {
2495 /* sind(180-x) = sind(x) */
2496 arg1 = 180.0 - arg1;
2497 }
2498
2499 result = sign * sind_q1(arg1);
2500
2501 if (unlikely(isinf(result)))
2503
2504 PG_RETURN_FLOAT8(result);
2505}

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 2615 of file float.c.

2616{
2618 float8 result;
2619
2620 errno = 0;
2621 result = sinh(arg1);
2622
2623 /*
2624 * if an ERANGE error occurs, it means there is an overflow. For sinh,
2625 * the result should be either -infinity or infinity, depending on the
2626 * sign of arg1.
2627 */
2628 if (errno == ERANGE)
2629 {
2630 if (arg1 < 0)
2631 result = -get_float8_infinity();
2632 else
2633 result = get_float8_infinity();
2634 }
2635
2636 PG_RETURN_FLOAT8(result);
2637}

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

◆ dsqrt()

Datum dsqrt ( PG_FUNCTION_ARGS  )

Definition at line 1463 of file float.c.

1464{
1466 float8 result;
1467
1468 if (arg1 < 0)
1469 ereport(ERROR,
1471 errmsg("cannot take square root of a negative number")));
1472
1473 result = sqrt(arg1);
1474 if (unlikely(isinf(result)) && !isinf(arg1))
1476 if (unlikely(result == 0.0) && arg1 != 0.0)
1478
1479 PG_RETURN_FLOAT8(result);
1480}

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 1982 of file float.c.

1983{
1985 float8 result;
1986
1987 /* Per the POSIX spec, return NaN if the input is NaN */
1988 if (isnan(arg1))
1990
1991 /* Be sure to throw an error if the input is infinite --- see dcos() */
1992 errno = 0;
1993 result = tan(arg1);
1994 if (errno != 0 || isinf(arg1))
1995 ereport(ERROR,
1997 errmsg("input is out of range")));
1998 /* Not checking for overflow because tan(pi/2) == Inf */
1999
2000 PG_RETURN_FLOAT8(result);
2001}

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 2512 of file float.c.

2513{
2515 float8 result;
2516 volatile float8 tan_arg1;
2517 int sign = 1;
2518
2519 /*
2520 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2521 * if the input is infinite.
2522 */
2523 if (isnan(arg1))
2525
2526 if (isinf(arg1))
2527 ereport(ERROR,
2529 errmsg("input is out of range")));
2530
2532
2533 /* Reduce the range of the input to [0,90] degrees */
2534 arg1 = fmod(arg1, 360.0);
2535
2536 if (arg1 < 0.0)
2537 {
2538 /* tand(-x) = -tand(x) */
2539 arg1 = -arg1;
2540 sign = -sign;
2541 }
2542
2543 if (arg1 > 180.0)
2544 {
2545 /* tand(360-x) = -tand(x) */
2546 arg1 = 360.0 - arg1;
2547 sign = -sign;
2548 }
2549
2550 if (arg1 > 90.0)
2551 {
2552 /* tand(180-x) = -tand(x) */
2553 arg1 = 180.0 - arg1;
2554 sign = -sign;
2555 }
2556
2558 result = sign * (tan_arg1 / tan_45);
2559
2560 /*
2561 * On some machines we get tand(180) = minus zero, but this isn't always
2562 * true. For portability, and because the user constituency for this
2563 * function probably doesn't want minus zero, force it to plain zero.
2564 */
2565 if (result == 0.0)
2566 result = 0.0;
2567
2568 /* Not checking for overflow because tand(90) == Inf */
2569
2570 PG_RETURN_FLOAT8(result);
2571}
static float8 tan_45
Definition float.c:66

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 2669 of file float.c.

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

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

◆ dtof()

Datum dtof ( PG_FUNCTION_ARGS  )

Definition at line 1212 of file float.c.

1213{
1214 float8 num = PG_GETARG_FLOAT8(0);
1215 float4 result;
1216
1217 result = (float4) num;
1218 if (unlikely(isinf(result)) && !isinf(num))
1220 if (unlikely(result == 0.0f) && num != 0.0)
1222
1223 PG_RETURN_FLOAT4(result);
1224}
#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 1256 of file float.c.

1257{
1258 float8 num = PG_GETARG_FLOAT8(0);
1259
1260 /*
1261 * Get rid of any fractional part in the input. This is so we don't fail
1262 * on just-out-of-range values that would round into range. Note
1263 * assumption that rint() will pass through a NaN or Inf unchanged.
1264 */
1265 num = rint(num);
1266
1267 /* Range check */
1268 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT16(num)))
1269 ereport(ERROR,
1271 errmsg("smallint out of range")));
1272
1273 PG_RETURN_INT16((int16) num);
1274}
int16_t int16
Definition c.h:613
#define FLOAT8_FITS_IN_INT16(num)
Definition c.h:1177
#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 1231 of file float.c.

1232{
1233 float8 num = PG_GETARG_FLOAT8(0);
1234
1235 /*
1236 * Get rid of any fractional part in the input. This is so we don't fail
1237 * on just-out-of-range values that would round into range. Note
1238 * assumption that rint() will pass through a NaN or Inf unchanged.
1239 */
1240 num = rint(num);
1241
1242 /* Range check */
1243 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT32(num)))
1244 ereport(ERROR,
1246 errmsg("integer out of range")));
1247
1248 PG_RETURN_INT32((int32) num);
1249}
#define FLOAT8_FITS_IN_INT32(num)
Definition c.h:1179
int32_t int32
Definition c.h:614

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 1445 of file float.c.

1446{
1448 float8 result;
1449
1450 if (arg1 >= 0)
1451 result = floor(arg1);
1452 else
1453 result = -floor(-arg1);
1454
1455 PG_RETURN_FLOAT8(result);
1456}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float48div()

Datum float48div ( PG_FUNCTION_ARGS  )

Definition at line 4019 of file float.c.

4020{
4023
4025}

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

◆ float48eq()

Datum float48eq ( PG_FUNCTION_ARGS  )

Definition at line 4079 of file float.c.

4080{
4083
4085}
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 4124 of file float.c.

4125{
4128
4130}
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 4115 of file float.c.

4116{
4119
4121}
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 4106 of file float.c.

4107{
4110
4112}
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 4097 of file float.c.

4098{
4101
4103}
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 4001 of file float.c.

4002{
4005
4007}
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 4010 of file float.c.

4011{
4014
4016}
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 4088 of file float.c.

4089{
4092
4094}
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 3992 of file float.c.

3993{
3996
3998}
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 3147 of file float.c.

3148{
3150
3151 /* do computations as float8 */
3154 float8 N,
3155 Sx,
3156 Sxx,
3157 tmp;
3158
3159 transvalues = check_float8_array(transarray, "float4_accum", 3);
3160 N = transvalues[0];
3161 Sx = transvalues[1];
3162 Sxx = transvalues[2];
3163
3164 /*
3165 * Use the Youngs-Cramer algorithm to incorporate the new value into the
3166 * transition values.
3167 */
3168 N += 1.0;
3169 Sx += newval;
3170 if (transvalues[0] > 0.0)
3171 {
3172 tmp = newval * N - Sx;
3173 Sxx += tmp * tmp / (N * transvalues[0]);
3174
3175 /*
3176 * Overflow check. We only report an overflow error when finite
3177 * inputs lead to infinite results. Note also that Sxx should be NaN
3178 * if any of the inputs are infinite, so we intentionally prevent Sxx
3179 * from becoming infinite.
3180 */
3181 if (isinf(Sx) || isinf(Sxx))
3182 {
3183 if (!isinf(transvalues[1]) && !isinf(newval))
3185
3186 Sxx = get_float8_nan();
3187 }
3188 }
3189 else
3190 {
3191 /*
3192 * At the first input, we normally can leave Sxx as 0. However, if
3193 * the first input is Inf or NaN, we'd better force Sxx to NaN;
3194 * otherwise we will falsely report variance zero when there are no
3195 * more inputs.
3196 */
3197 if (isnan(newval) || isinf(newval))
3198 Sxx = get_float8_nan();
3199 }
3200
3201 /*
3202 * If we're invoked as an aggregate, we can cheat and modify our first
3203 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3204 * new array with the updated transition data and return it.
3205 */
3206 if (AggCheckCallContext(fcinfo, NULL))
3207 {
3208 transvalues[0] = N;
3209 transvalues[1] = Sx;
3210 transvalues[2] = Sxx;
3211
3213 }
3214 else
3215 {
3216 Datum transdatums[3];
3217 ArrayType *result;
3218
3222
3224
3225 PG_RETURN_ARRAYTYPE_P(result);
3226 }
3227}
#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:2950
#define newval
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition nodeAgg.c:4609
#define Float8GetDatumFast(X)
Definition postgres.h:527
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 833 of file float.c.

834{
835 if (float4_gt(a, b))
836 return 1;
837 if (float4_lt(a, b))
838 return -1;
839 return 0;
840}
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 608 of file float.c.

609{
611
613}

References fb(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4div()

Datum float4div ( PG_FUNCTION_ARGS  )

Definition at line 772 of file float.c.

773{
776
778}
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 843 of file float.c.

844{
847
849}
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 888 of file float.c.

889{
892
894}
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 879 of file float.c.

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

◆ float4in()

Datum float4in ( PG_FUNCTION_ARGS  )

Definition at line 181 of file float.c.

182{
183 char *num = PG_GETARG_CSTRING(0);
184
185 PG_RETURN_FLOAT4(float4in_internal(num, NULL, "real", num,
186 fcinfo->context));
187}
float4 float4in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:200
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278

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

Referenced by import_pg_statistic(), and 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 200 of file float.c.

203{
204 float val;
205 char *endptr;
206
207 /*
208 * endptr points to the first character _after_ the sequence we recognized
209 * as a valid floating point number. orig_string points to the original
210 * input string.
211 */
212
213 /* skip leading whitespace */
214 while (*num != '\0' && isspace((unsigned char) *num))
215 num++;
216
217 /*
218 * Check for an empty-string input to begin with, to avoid the vagaries of
219 * strtod() on different platforms.
220 */
221 if (*num == '\0')
222 ereturn(escontext, 0,
224 errmsg("invalid input syntax for type %s: \"%s\"",
225 type_name, orig_string)));
226
227 errno = 0;
228 val = strtof(num, &endptr);
229
230 /* did we not see anything that looks like a double? */
231 if (endptr == num || errno != 0)
232 {
233 int save_errno = errno;
234
235 /*
236 * C99 requires that strtof() accept NaN, [+-]Infinity, and [+-]Inf,
237 * but not all platforms support all of these (and some accept them
238 * but set ERANGE anyway...) Therefore, we check for these inputs
239 * ourselves if strtof() fails.
240 *
241 * Note: C99 also requires hexadecimal input as well as some extended
242 * forms of NaN, but we consider these forms unportable and don't try
243 * to support them. You can use 'em if your strtof() takes 'em.
244 */
245 if (pg_strncasecmp(num, "NaN", 3) == 0)
246 {
248 endptr = num + 3;
249 }
250 else if (pg_strncasecmp(num, "Infinity", 8) == 0)
251 {
253 endptr = num + 8;
254 }
255 else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
256 {
258 endptr = num + 9;
259 }
260 else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
261 {
263 endptr = num + 9;
264 }
265 else if (pg_strncasecmp(num, "inf", 3) == 0)
266 {
268 endptr = num + 3;
269 }
270 else if (pg_strncasecmp(num, "+inf", 4) == 0)
271 {
273 endptr = num + 4;
274 }
275 else if (pg_strncasecmp(num, "-inf", 4) == 0)
276 {
278 endptr = num + 4;
279 }
280 else if (save_errno == ERANGE)
281 {
282 /*
283 * Some platforms return ERANGE for denormalized numbers (those
284 * that are not zero, but are too close to zero to have full
285 * precision). We'd prefer not to throw error for that, so try to
286 * detect whether it's a "real" out-of-range condition by checking
287 * to see if the result is zero or huge.
288 */
289 if (val == 0.0 ||
290#if !defined(HUGE_VALF)
291 isinf(val)
292#else
293 (val >= HUGE_VALF || val <= -HUGE_VALF)
294#endif
295 )
296 {
297 /* see comments in float8in_internal for rationale */
298 char *errnumber = pstrdup(num);
299
300 errnumber[endptr - num] = '\0';
301
302 ereturn(escontext, 0,
304 errmsg("\"%s\" is out of range for type real",
305 errnumber)));
306 }
307 }
308 else
309 ereturn(escontext, 0,
311 errmsg("invalid input syntax for type %s: \"%s\"",
312 type_name, orig_string)));
313 }
314
315 /* skip trailing whitespace */
316 while (*endptr != '\0' && isspace((unsigned char) *endptr))
317 endptr++;
318
319 /* report stopping point if wanted, else complain if not end of string */
320 if (endptr_p)
321 *endptr_p = endptr;
322 else if (*endptr != '\0')
323 ereturn(escontext, 0,
325 errmsg("invalid input syntax for type %s: \"%s\"",
326 type_name, orig_string)));
327
328 return val;
329}
#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 637 of file float.c.

638{
641 float4 result;
642
643 if (float4_gt(arg1, arg2))
644 result = arg1;
645 else
646 result = arg2;
647 PG_RETURN_FLOAT4(result);
648}

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

◆ float4le()

Datum float4le ( PG_FUNCTION_ARGS  )

Definition at line 870 of file float.c.

871{
874
876}
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 861 of file float.c.

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

◆ float4mi()

Datum float4mi ( PG_FUNCTION_ARGS  )

Definition at line 754 of file float.c.

755{
758
760}
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 763 of file float.c.

764{
767
769}
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 852 of file float.c.

853{
856
858}
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 336 of file float.c.

337{
338 float4 num = PG_GETARG_FLOAT4(0);
339 char *ascii = (char *) palloc(32);
341
342 if (extra_float_digits > 0)
343 {
346 }
347
348 (void) pg_strfromd(ascii, 32, ndig, num);
350}
int float_to_shortest_decimal_buf(float f, char *result)
Definition f2s.c:780
int extra_float_digits
Definition float.c:57
#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 745 of file float.c.

746{
749
751}
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 356 of file float.c.

357{
359
361}
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 367 of file float.c.

368{
369 float4 num = PG_GETARG_FLOAT4(0);
371
373 pq_sendfloat4(&buf, num);
375}
#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 651 of file float.c.

652{
655 float4 result;
656
657 if (float4_lt(arg1, arg2))
658 result = arg1;
659 else
660 result = arg2;
661 PG_RETURN_FLOAT4(result);
662}

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

◆ float4um()

Datum float4um ( PG_FUNCTION_ARGS  )

Definition at line 619 of file float.c.

620{
622 float4 result;
623
624 result = -arg1;
625 PG_RETURN_FLOAT4(result);
626}

References fb(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4up()

Datum float4up ( PG_FUNCTION_ARGS  )

Definition at line 629 of file float.c.

630{
632
634}
Datum arg
Definition elog.c:1322

References arg, PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float84div()

Datum float84div ( PG_FUNCTION_ARGS  )

Definition at line 4061 of file float.c.

4062{
4065
4067}

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

◆ float84eq()

Datum float84eq ( PG_FUNCTION_ARGS  )

Definition at line 4136 of file float.c.

4137{
4140
4142}

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

◆ float84ge()

Datum float84ge ( PG_FUNCTION_ARGS  )

Definition at line 4181 of file float.c.

4182{
4185
4187}

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

◆ float84gt()

Datum float84gt ( PG_FUNCTION_ARGS  )

Definition at line 4172 of file float.c.

4173{
4176
4178}

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

◆ float84le()

Datum float84le ( PG_FUNCTION_ARGS  )

Definition at line 4163 of file float.c.

4164{
4167
4169}

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

◆ float84lt()

Datum float84lt ( PG_FUNCTION_ARGS  )

Definition at line 4154 of file float.c.

4155{
4158
4160}

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

◆ float84mi()

Datum float84mi ( PG_FUNCTION_ARGS  )

Definition at line 4043 of file float.c.

4044{
4047
4049}

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

◆ float84mul()

Datum float84mul ( PG_FUNCTION_ARGS  )

Definition at line 4052 of file float.c.

4053{
4056
4058}

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

◆ float84ne()

Datum float84ne ( PG_FUNCTION_ARGS  )

Definition at line 4145 of file float.c.

4146{
4149
4151}

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

◆ float84pl()

Datum float84pl ( PG_FUNCTION_ARGS  )

Definition at line 4034 of file float.c.

4035{
4038
4040}

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 3066 of file float.c.

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

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 3230 of file float.c.

3231{
3234 float8 N,
3235 Sx;
3236
3237 transvalues = check_float8_array(transarray, "float8_avg", 3);
3238 N = transvalues[0];
3239 Sx = transvalues[1];
3240 /* ignore Sxx */
3241
3242 /* SQL defines AVG of no values to be NULL */
3243 if (N == 0.0)
3245
3246 PG_RETURN_FLOAT8(Sx / N);
3247}
#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 927 of file float.c.

928{
929 if (float8_gt(a, b))
930 return 1;
931 if (float8_lt(a, b))
932 return -1;
933 return 0;
934}

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 2974 of file float.c.

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

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 3834 of file float.c.

3835{
3838 float8 N,
3839 Sxx,
3840 Syy,
3841 Sxy,
3842 product,
3844 result;
3845
3846 transvalues = check_float8_array(transarray, "float8_corr", 8);
3847 N = transvalues[0];
3848 Sxx = transvalues[2];
3849 Syy = transvalues[4];
3850 Sxy = transvalues[5];
3851
3852 /* if N is 0 we should return NULL */
3853 if (N < 1.0)
3855
3856 /* Note that Sxx and Syy are guaranteed to be non-negative */
3857
3858 /* per spec, return NULL for horizontal and vertical lines */
3859 if (Sxx == 0 || Syy == 0)
3861
3862 /*
3863 * The product Sxx * Syy might underflow or overflow. If so, we can
3864 * recover by computing sqrt(Sxx) * sqrt(Syy) instead of sqrt(Sxx * Syy).
3865 * However, the double sqrt() calculation is a bit slower and less
3866 * accurate, so don't do it if we don't have to.
3867 */
3868 product = Sxx * Syy;
3869 if (product == 0 || isinf(product))
3870 sqrtproduct = sqrt(Sxx) * sqrt(Syy);
3871 else
3873 result = Sxy / sqrtproduct;
3874
3875 /*
3876 * Despite all these precautions, this formula can yield results outside
3877 * [-1, 1] due to roundoff error. Clamp it to the expected range.
3878 */
3879 if (result < -1)
3880 result = -1;
3881 else if (result > 1)
3882 result = 1;
3883
3884 PG_RETURN_FLOAT8(result);
3885}

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 3796 of file float.c.

3797{
3800 float8 N,
3801 Sxy;
3802
3803 transvalues = check_float8_array(transarray, "float8_covar_pop", 8);
3804 N = transvalues[0];
3805 Sxy = transvalues[5];
3806
3807 /* if N is 0 we should return NULL */
3808 if (N < 1.0)
3810
3811 PG_RETURN_FLOAT8(Sxy / N);
3812}

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 3815 of file float.c.

3816{
3819 float8 N,
3820 Sxy;
3821
3822 transvalues = check_float8_array(transarray, "float8_covar_samp", 8);
3823 N = transvalues[0];
3824 Sxy = transvalues[5];
3825
3826 /* if N is <= 1 we should return NULL */
3827 if (N < 2.0)
3829
3830 PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3831}

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 3371 of file float.c.

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

3747{
3750 float8 N,
3751 Sx,
3752 commonX;
3753
3754 transvalues = check_float8_array(transarray, "float8_regr_avgx", 8);
3755 N = transvalues[0];
3756 Sx = transvalues[1];
3757 commonX = transvalues[6];
3758
3759 /* if N is 0 we should return NULL */
3760 if (N < 1.0)
3762
3763 /* if all inputs were the same just return that, avoiding roundoff error */
3764 if (!isnan(commonX))
3766
3767 PG_RETURN_FLOAT8(Sx / N);
3768}

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 3771 of file float.c.

3772{
3775 float8 N,
3776 Sy,
3777 commonY;
3778
3779 transvalues = check_float8_array(transarray, "float8_regr_avgy", 8);
3780 N = transvalues[0];
3781 Sy = transvalues[3];
3782 commonY = transvalues[7];
3783
3784 /* if N is 0 we should return NULL */
3785 if (N < 1.0)
3787
3788 /* if all inputs were the same just return that, avoiding roundoff error */
3789 if (!isnan(commonY))
3791
3792 PG_RETURN_FLOAT8(Sy / N);
3793}

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 3525 of file float.c.

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

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 3948 of file float.c.

3949{
3952 float8 N,
3953 Sx,
3954 Sxx,
3955 Sy,
3956 Sxy;
3957
3958 transvalues = check_float8_array(transarray, "float8_regr_intercept", 8);
3959 N = transvalues[0];
3960 Sx = transvalues[1];
3961 Sxx = transvalues[2];
3962 Sy = transvalues[3];
3963 Sxy = transvalues[5];
3964
3965 /* if N is 0 we should return NULL */
3966 if (N < 1.0)
3968
3969 /* Note that Sxx is guaranteed to be non-negative */
3970
3971 /* per spec, return NULL for a vertical line */
3972 if (Sxx == 0)
3974
3975 PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
3976}

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 3888 of file float.c.

3889{
3892 float8 N,
3893 Sxx,
3894 Syy,
3895 Sxy;
3896
3897 transvalues = check_float8_array(transarray, "float8_regr_r2", 8);
3898 N = transvalues[0];
3899 Sxx = transvalues[2];
3900 Syy = transvalues[4];
3901 Sxy = transvalues[5];
3902
3903 /* if N is 0 we should return NULL */
3904 if (N < 1.0)
3906
3907 /* Note that Sxx and Syy are guaranteed to be non-negative */
3908
3909 /* per spec, return NULL for a vertical line */
3910 if (Sxx == 0)
3912
3913 /* per spec, return 1.0 for a horizontal line */
3914 if (Syy == 0)
3915 PG_RETURN_FLOAT8(1.0);
3916
3917 PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3918}

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 3921 of file float.c.

3922{
3925 float8 N,
3926 Sxx,
3927 Sxy;
3928
3929 transvalues = check_float8_array(transarray, "float8_regr_slope", 8);
3930 N = transvalues[0];
3931 Sxx = transvalues[2];
3932 Sxy = transvalues[5];
3933
3934 /* if N is 0 we should return NULL */
3935 if (N < 1.0)
3937
3938 /* Note that Sxx is guaranteed to be non-negative */
3939
3940 /* per spec, return NULL for a vertical line */
3941 if (Sxx == 0)
3943
3945}

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 3683 of file float.c.

3684{
3687 float8 N,
3688 Sxx;
3689
3690 transvalues = check_float8_array(transarray, "float8_regr_sxx", 8);
3691 N = transvalues[0];
3692 Sxx = transvalues[2];
3693
3694 /* if N is 0 we should return NULL */
3695 if (N < 1.0)
3697
3698 /* Note that Sxx is guaranteed to be non-negative */
3699
3701}

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 3725 of file float.c.

3726{
3729 float8 N,
3730 Sxy;
3731
3732 transvalues = check_float8_array(transarray, "float8_regr_sxy", 8);
3733 N = transvalues[0];
3734 Sxy = transvalues[5];
3735
3736 /* if N is 0 we should return NULL */
3737 if (N < 1.0)
3739
3740 /* A negative result is valid here */
3741
3743}

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 3704 of file float.c.

3705{
3708 float8 N,
3709 Syy;
3710
3711 transvalues = check_float8_array(transarray, "float8_regr_syy", 8);
3712 N = transvalues[0];
3713 Syy = transvalues[4];
3714
3715 /* if N is 0 we should return NULL */
3716 if (N < 1.0)
3718
3719 /* Note that Syy is guaranteed to be non-negative */
3720
3722}

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 3294 of file float.c.

3295{
3298 float8 N,
3299 Sxx;
3300
3301 transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
3302 N = transvalues[0];
3303 /* ignore Sx */
3304 Sxx = transvalues[2];
3305
3306 /* Population stddev is undefined when N is 0, so return NULL */
3307 if (N == 0.0)
3309
3310 /* Note that Sxx is guaranteed to be non-negative */
3311
3313}

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 3316 of file float.c.

3317{
3320 float8 N,
3321 Sxx;
3322
3323 transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
3324 N = transvalues[0];
3325 /* ignore Sx */
3326 Sxx = transvalues[2];
3327
3328 /* Sample stddev is undefined when N is 0 or 1, so return NULL */
3329 if (N <= 1.0)
3331
3332 /* Note that Sxx is guaranteed to be non-negative */
3333
3334 PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0)));
3335}

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 3250 of file float.c.

3251{
3254 float8 N,
3255 Sxx;
3256
3257 transvalues = check_float8_array(transarray, "float8_var_pop", 3);
3258 N = transvalues[0];
3259 /* ignore Sx */
3260 Sxx = transvalues[2];
3261
3262 /* Population variance is undefined when N is 0, so return NULL */
3263 if (N == 0.0)
3265
3266 /* Note that Sxx is guaranteed to be non-negative */
3267
3268 PG_RETURN_FLOAT8(Sxx / N);
3269}

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 3272 of file float.c.

3273{
3276 float8 N,
3277 Sxx;
3278
3279 transvalues = check_float8_array(transarray, "float8_var_samp", 3);
3280 N = transvalues[0];
3281 /* ignore Sx */
3282 Sxx = transvalues[2];
3283
3284 /* Sample variance is undefined when N is 0 or 1, so return NULL */
3285 if (N <= 1.0)
3287
3288 /* Note that Sxx is guaranteed to be non-negative */
3289
3290 PG_RETURN_FLOAT8(Sxx / (N - 1.0));
3291}

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 674 of file float.c.

675{
677
679}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8div()

Datum float8div ( PG_FUNCTION_ARGS  )

Definition at line 814 of file float.c.

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

◆ float8eq()

Datum float8eq ( PG_FUNCTION_ARGS  )

Definition at line 937 of file float.c.

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

◆ float8ge()

Datum float8ge ( PG_FUNCTION_ARGS  )

Definition at line 982 of file float.c.

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

◆ float8gt()

Datum float8gt ( PG_FUNCTION_ARGS  )

Definition at line 973 of file float.c.

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

◆ float8in()

Datum float8in ( PG_FUNCTION_ARGS  )

Definition at line 381 of file float.c.

382{
383 char *num = PG_GETARG_CSTRING(0);
384
385 PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num,
386 fcinfo->context));
387}
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:412

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 412 of file float.c.

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

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 704 of file float.c.

705{
708 float8 result;
709
710 if (float8_gt(arg1, arg2))
711 result = arg1;
712 else
713 result = arg2;
714 PG_RETURN_FLOAT8(result);
715}

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

◆ float8le()

Datum float8le ( PG_FUNCTION_ARGS  )

Definition at line 964 of file float.c.

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

◆ float8lt()

Datum float8lt ( PG_FUNCTION_ARGS  )

Definition at line 955 of file float.c.

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

◆ float8mi()

Datum float8mi ( PG_FUNCTION_ARGS  )

Definition at line 796 of file float.c.

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

◆ float8mul()

Datum float8mul ( PG_FUNCTION_ARGS  )

Definition at line 805 of file float.c.

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

◆ float8ne()

Datum float8ne ( PG_FUNCTION_ARGS  )

Definition at line 946 of file float.c.

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

◆ float8out()

Datum float8out ( PG_FUNCTION_ARGS  )

Definition at line 539 of file float.c.

540{
541 float8 num = PG_GETARG_FLOAT8(0);
542
544}
char * float8out_internal(double num)
Definition float.c:554

References float8out_internal(), PG_GETARG_FLOAT8, and PG_RETURN_CSTRING.

◆ float8out_internal()

char * float8out_internal ( double  num)

Definition at line 554 of file float.c.

555{
556 char *ascii = (char *) palloc(32);
558
559 if (extra_float_digits > 0)
560 {
562 return ascii;
563 }
564
565 (void) pg_strfromd(ascii, 32, ndig, num);
566 return ascii;
567}
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 787 of file float.c.

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

◆ float8recv()

Datum float8recv ( PG_FUNCTION_ARGS  )

Definition at line 573 of file float.c.

574{
576
578}
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 584 of file float.c.

585{
586 float8 num = PG_GETARG_FLOAT8(0);
588
590 pq_sendfloat8(&buf, num);
592}
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 718 of file float.c.

719{
722 float8 result;
723
724 if (float8_lt(arg1, arg2))
725 result = arg1;
726 else
727 result = arg2;
728 PG_RETURN_FLOAT8(result);
729}

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

◆ float8um()

Datum float8um ( PG_FUNCTION_ARGS  )

Definition at line 686 of file float.c.

687{
689 float8 result;
690
691 result = -arg1;
692 PG_RETURN_FLOAT8(result);
693}

References fb(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8up()

Datum float8up ( PG_FUNCTION_ARGS  )

Definition at line 696 of file float.c.

697{
699
701}

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 111 of file float.c.

112{
115 errmsg("value out of range: underflow")));
116}

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 119 of file float.c.

120{
123 errmsg("division by zero")));
124}

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

Referenced by float4_div(), and float8_div().

◆ ftod()

Datum ftod ( PG_FUNCTION_ARGS  )

Definition at line 1200 of file float.c.

1201{
1202 float4 num = PG_GETARG_FLOAT4(0);
1203
1204 PG_RETURN_FLOAT8((float8) num);
1205}

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT8.

◆ ftoi2()

Datum ftoi2 ( PG_FUNCTION_ARGS  )

Definition at line 1330 of file float.c.

1331{
1332 float4 num = PG_GETARG_FLOAT4(0);
1333
1334 /*
1335 * Get rid of any fractional part in the input. This is so we don't fail
1336 * on just-out-of-range values that would round into range. Note
1337 * assumption that rint() will pass through a NaN or Inf unchanged.
1338 */
1339 num = rint(num);
1340
1341 /* Range check */
1342 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT16(num)))
1343 ereport(ERROR,
1345 errmsg("smallint out of range")));
1346
1347 PG_RETURN_INT16((int16) num);
1348}
#define FLOAT4_FITS_IN_INT16(num)
Definition c.h:1171

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 1305 of file float.c.

1306{
1307 float4 num = PG_GETARG_FLOAT4(0);
1308
1309 /*
1310 * Get rid of any fractional part in the input. This is so we don't fail
1311 * on just-out-of-range values that would round into range. Note
1312 * assumption that rint() will pass through a NaN or Inf unchanged.
1313 */
1314 num = rint(num);
1315
1316 /* Range check */
1317 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT32(num)))
1318 ereport(ERROR,
1320 errmsg("integer out of range")));
1321
1322 PG_RETURN_INT32((int32) num);
1323}
#define FLOAT4_FITS_IN_INT32(num)
Definition c.h:1173

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 1293 of file float.c.

1294{
1295 int16 num = PG_GETARG_INT16(0);
1296
1297 PG_RETURN_FLOAT8((float8) num);
1298}
#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 1367 of file float.c.

1368{
1369 int16 num = PG_GETARG_INT16(0);
1370
1371 PG_RETURN_FLOAT4((float4) num);
1372}

References PG_GETARG_INT16, and PG_RETURN_FLOAT4.

◆ i4tod()

Datum i4tod ( PG_FUNCTION_ARGS  )

Definition at line 1281 of file float.c.

1282{
1283 int32 num = PG_GETARG_INT32(0);
1284
1285 PG_RETURN_FLOAT8((float8) num);
1286}
#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 1355 of file float.c.

1356{
1357 int32 num = PG_GETARG_INT32(0);
1358
1359 PG_RETURN_FLOAT4((float4) num);
1360}

References PG_GETARG_INT32, and PG_RETURN_FLOAT4.

◆ in_range_float4_float8()

Datum in_range_float4_float8 ( PG_FUNCTION_ARGS  )

Definition at line 1120 of file float.c.

1121{
1123 float4 base = PG_GETARG_FLOAT4(1);
1124 float8 offset = PG_GETARG_FLOAT8(2);
1125 bool sub = PG_GETARG_BOOL(3);
1126 bool less = PG_GETARG_BOOL(4);
1127 float8 sum;
1128
1129 /*
1130 * Reject negative or NaN offset. Negative is per spec, and NaN is
1131 * because appropriate semantics for that seem non-obvious.
1132 */
1133 if (isnan(offset) || offset < 0)
1134 ereport(ERROR,
1136 errmsg("invalid preceding or following size in window function")));
1137
1138 /*
1139 * Deal with cases where val and/or base is NaN, following the rule that
1140 * NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1141 * affect the conclusion.
1142 */
1143 if (isnan(val))
1144 {
1145 if (isnan(base))
1146 PG_RETURN_BOOL(true); /* NAN = NAN */
1147 else
1148 PG_RETURN_BOOL(!less); /* NAN > non-NAN */
1149 }
1150 else if (isnan(base))
1151 {
1152 PG_RETURN_BOOL(less); /* non-NAN < NAN */
1153 }
1154
1155 /*
1156 * Deal with cases where both base and offset are infinite, and computing
1157 * base +/- offset would produce NaN. This corresponds to a window frame
1158 * whose boundary infinitely precedes +inf or infinitely follows -inf,
1159 * which is not well-defined. For consistency with other cases involving
1160 * infinities, such as the fact that +inf infinitely follows +inf, we
1161 * choose to assume that +inf infinitely precedes +inf and -inf infinitely
1162 * follows -inf, and therefore that all finite and infinite values are in
1163 * such a window frame.
1164 *
1165 * offset is known positive, so we need only check the sign of base in
1166 * this test.
1167 */
1168 if (isinf(offset) && isinf(base) &&
1169 (sub ? base > 0 : base < 0))
1171
1172 /*
1173 * Otherwise it should be safe to compute base +/- offset. We trust the
1174 * FPU to cope if an input is +/-inf or the true sum would overflow, and
1175 * produce a suitably signed infinity, which will compare properly against
1176 * val whether or not that's infinity.
1177 */
1178 if (sub)
1179 sum = base - offset;
1180 else
1181 sum = base + offset;
1182
1183 if (less)
1184 PG_RETURN_BOOL(val <= sum);
1185 else
1186 PG_RETURN_BOOL(val >= sum);
1187}
#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 1044 of file float.c.

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

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 135 of file float.c.

136{
137 int inf = isinf(val);
138
139 if (inf == 0)
140 return 0;
141 else if (val > 0)
142 return 1;
143 else
144 return -1;
145}

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 2269 of file float.c.

2270{
2271 volatile float8 sin_x = sin(x * RADIANS_PER_DEGREE);
2272
2273 return (sin_x / sin_30) / 2.0;
2274}

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 2296 of file float.c.

2297{
2298 /*
2299 * Stitch together the sine and cosine functions for the ranges [0, 30]
2300 * and (30, 90]. These guarantee to return exact answers at their
2301 * endpoints, so the overall result is a continuous monotonic function
2302 * that gives exact results when x = 0, 30 and 90 degrees.
2303 */
2304 if (x <= 30.0)
2305 return sind_0_to_30(x);
2306 else
2307 return cosd_0_to_60(90.0 - x);
2308}

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 4205 of file float.c.

4206{
4207 float8 operand = PG_GETARG_FLOAT8(0);
4210 int32 count = PG_GETARG_INT32(3);
4211 int32 result;
4212
4213 if (count <= 0)
4214 ereport(ERROR,
4216 errmsg("count must be greater than zero")));
4217
4218 if (isnan(bound1) || isnan(bound2))
4219 ereport(ERROR,
4221 errmsg("lower and upper bounds cannot be NaN")));
4222
4223 if (isinf(bound1) || isinf(bound2))
4224 ereport(ERROR,
4226 errmsg("lower and upper bounds must be finite")));
4227
4228 if (bound1 < bound2)
4229 {
4230 if (isnan(operand) || operand >= bound2)
4231 {
4232 if (pg_add_s32_overflow(count, 1, &result))
4233 ereport(ERROR,
4235 errmsg("integer out of range")));
4236 }
4237 else if (operand < bound1)
4238 result = 0;
4239 else
4240 {
4241 if (!isinf(bound2 - bound1))
4242 {
4243 /* The quotient is surely in [0,1], so this can't overflow */
4244 result = count * ((operand - bound1) / (bound2 - bound1));
4245 }
4246 else
4247 {
4248 /*
4249 * We get here if bound2 - bound1 overflows DBL_MAX. Since
4250 * both bounds are finite, their difference can't exceed twice
4251 * DBL_MAX; so we can perform the computation without overflow
4252 * by dividing all the inputs by 2. That should be exact too,
4253 * except in the case where a very small operand underflows to
4254 * zero, which would have negligible impact on the result
4255 * given such large bounds.
4256 */
4257 result = count * ((operand / 2 - bound1 / 2) / (bound2 / 2 - bound1 / 2));
4258 }
4259 /* The quotient could round to 1.0, which would be a lie */
4260 if (result >= count)
4261 result = count - 1;
4262 /* Having done that, we can add 1 without fear of overflow */
4263 result++;
4264 }
4265 }
4266 else if (bound1 > bound2)
4267 {
4268 if (isnan(operand) || operand > bound1)
4269 result = 0;
4270 else if (operand <= bound2)
4271 {
4272 if (pg_add_s32_overflow(count, 1, &result))
4273 ereport(ERROR,
4275 errmsg("integer out of range")));
4276 }
4277 else
4278 {
4279 if (!isinf(bound1 - bound2))
4280 result = count * ((bound1 - operand) / (bound1 - bound2));
4281 else
4282 result = count * ((bound1 / 2 - operand / 2) / (bound1 / 2 - bound2 / 2));
4283 if (result >= count)
4284 result = count - 1;
4285 result++;
4286 }
4287 }
4288 else
4289 {
4290 ereport(ERROR,
4292 errmsg("lower bound cannot equal upper bound")));
4293 result = 0; /* keep the compiler quiet */
4294 }
4295
4296 PG_RETURN_INT32(result);
4297}
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 64 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 63 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 65 of file float.c.

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

◆ cot_45

float8 cot_45 = 0
static

Definition at line 67 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 84 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_one

float8 degree_c_one = 1.0

Definition at line 87 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_one_half

float8 degree_c_one_half = 0.5

Definition at line 86 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_sixty

float8 degree_c_sixty = 60.0

Definition at line 85 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_thirty

float8 degree_c_thirty = 30.0

Definition at line 83 of file float.c.

Referenced by init_degree_constants().

◆ degree_consts_set

bool degree_consts_set = false
static

Definition at line 60 of file float.c.

Referenced by init_degree_constants().

◆ extra_float_digits

int extra_float_digits = 1

Definition at line 57 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 62 of file float.c.

Referenced by cosd_0_to_60(), and init_degree_constants().

◆ sin_30

float8 sin_30 = 0
static

Definition at line 61 of file float.c.

Referenced by init_degree_constants(), and sind_0_to_30().

◆ tan_45

float8 tan_45 = 0
static

Definition at line 66 of file float.c.

Referenced by dtand(), and init_degree_constants().