PostgreSQL Source Code  git master
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 "utils/timestamp.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)
 
char * float8out_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)
 
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 { \
init_degree_constants(); \
} while(0)
static bool degree_consts_set
Definition: float.c:44

Definition at line 2032 of file float.c.

Function Documentation

◆ acosd_q1()

static double acosd_q1 ( double  x)
static

Definition at line 2082 of file float.c.

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

References acos_0_5, asin_0_5, and x.

Referenced by dacosd().

◆ asind_q1()

static double asind_q1 ( double  x)
static

Definition at line 2049 of file float.c.

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

References acos_0_5, asin_0_5, and x.

Referenced by dacosd(), and dasind().

◆ btfloat48cmp()

Datum btfloat48cmp ( PG_FUNCTION_ARGS  )

Definition at line 1002 of file float.c.

1003 {
1004  float4 arg1 = PG_GETARG_FLOAT4(0);
1005  float8 arg2 = PG_GETARG_FLOAT8(1);
1006 
1007  /* widen float4 to float8 and then compare */
1008  PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
1009 }
float float4
Definition: c.h:629
int float8_cmp_internal(float8 a, float8 b)
Definition: float.c:911
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GETARG_FLOAT4(n)
Definition: fmgr.h:281

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

◆ btfloat4cmp()

Datum btfloat4cmp ( PG_FUNCTION_ARGS  )

Definition at line 881 of file float.c.

882 {
883  float4 arg1 = PG_GETARG_FLOAT4(0);
884  float4 arg2 = PG_GETARG_FLOAT4(1);
885 
887 }
int float4_cmp_internal(float4 a, float4 b)
Definition: float.c:817

References float4_cmp_internal(), PG_GETARG_FLOAT4, and PG_RETURN_INT32.

◆ btfloat4fastcmp()

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

Definition at line 890 of file float.c.

891 {
892  float4 arg1 = DatumGetFloat4(x);
893  float4 arg2 = DatumGetFloat4(y);
894 
895  return float4_cmp_internal(arg1, arg2);
896 }
int y
Definition: isn.c:72
static float4 DatumGetFloat4(Datum X)
Definition: postgres.h:458

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

Referenced by btfloat4sortsupport().

◆ btfloat4sortsupport()

Datum btfloat4sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 899 of file float.c.

900 {
902 
903  ssup->comparator = btfloat4fastcmp;
904  PG_RETURN_VOID();
905 }
static int btfloat4fastcmp(Datum x, Datum y, SortSupport ssup)
Definition: float.c:890
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106

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

◆ btfloat84cmp()

Datum btfloat84cmp ( PG_FUNCTION_ARGS  )

Definition at line 1012 of file float.c.

1013 {
1014  float8 arg1 = PG_GETARG_FLOAT8(0);
1015  float4 arg2 = PG_GETARG_FLOAT4(1);
1016 
1017  /* widen float4 to float8 and then compare */
1018  PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
1019 }

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

◆ btfloat8cmp()

Datum btfloat8cmp ( PG_FUNCTION_ARGS  )

Definition at line 975 of file float.c.

976 {
977  float8 arg1 = PG_GETARG_FLOAT8(0);
978  float8 arg2 = PG_GETARG_FLOAT8(1);
979 
981 }

References float8_cmp_internal(), PG_GETARG_FLOAT8, and PG_RETURN_INT32.

◆ btfloat8fastcmp()

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

Definition at line 984 of file float.c.

985 {
986  float8 arg1 = DatumGetFloat8(x);
987  float8 arg2 = DatumGetFloat8(y);
988 
989  return float8_cmp_internal(arg1, arg2);
990 }
static float8 DatumGetFloat8(Datum X)
Definition: postgres.h:494

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

Referenced by btfloat8sortsupport().

◆ btfloat8sortsupport()

Datum btfloat8sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 993 of file float.c.

994 {
996 
997  ssup->comparator = btfloat8fastcmp;
998  PG_RETURN_VOID();
999 }
static int btfloat8fastcmp(Datum x, Datum y, SortSupport ssup)
Definition: float.c:984

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

2841 {
2842  /*
2843  * We expect the input to be an N-element float array; verify that. We
2844  * don't need to use deconstruct_array() since the array data is just
2845  * going to look like a C array of N float8 values.
2846  */
2847  if (ARR_NDIM(transarray) != 1 ||
2848  ARR_DIMS(transarray)[0] != n ||
2849  ARR_HASNULL(transarray) ||
2850  ARR_ELEMTYPE(transarray) != FLOAT8OID)
2851  elog(ERROR, "%s: expected %d-element float8 array", caller, n);
2852  return (float8 *) ARR_DATA_PTR(transarray);
2853 }
#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:224

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, elog, and ERROR.

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

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

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

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

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

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

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

◆ dacosd()

Datum dacosd ( PG_FUNCTION_ARGS  )

Definition at line 2109 of file float.c.

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

References acosd_q1(), asind_q1(), ereport, errcode(), errmsg(), ERROR, 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 2690 of file float.c.

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

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

◆ dasin()

Datum dasin ( PG_FUNCTION_ARGS  )

Definition at line 1787 of file float.c.

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

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

◆ dasind()

Datum dasind ( PG_FUNCTION_ARGS  )

Definition at line 2146 of file float.c.

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

References asind_q1(), ereport, errcode(), errmsg(), ERROR, 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 2673 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ datan()

Datum datan ( PG_FUNCTION_ARGS  )

Definition at line 1818 of file float.c.

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

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

◆ datan2()

Datum datan2 ( PG_FUNCTION_ARGS  )

Definition at line 1844 of file float.c.

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

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

◆ datan2d()

Datum datan2d ( PG_FUNCTION_ARGS  )

Definition at line 2215 of file float.c.

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

References atan_1_0, 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 2183 of file float.c.

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

References atan_1_0, 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 2715 of file float.c.

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

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

◆ dcbrt()

Datum dcbrt ( PG_FUNCTION_ARGS  )

Definition at line 1471 of file float.c.

1472 {
1473  float8 arg1 = PG_GETARG_FLOAT8(0);
1474  float8 result;
1475 
1476  result = cbrt(arg1);
1477  if (unlikely(isinf(result)) && !isinf(arg1))
1479  if (unlikely(result == 0.0) && arg1 != 0.0)
1481 
1482  PG_RETURN_FLOAT8(result);
1483 }
pg_noinline void float_underflow_error(void)
Definition: float.c:95

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

◆ dceil()

Datum dceil ( PG_FUNCTION_ARGS  )

Definition at line 1381 of file float.c.

1382 {
1383  float8 arg1 = PG_GETARG_FLOAT8(0);
1384 
1385  PG_RETURN_FLOAT8(ceil(arg1));
1386 }

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dcos()

Datum dcos ( PG_FUNCTION_ARGS  )

Definition at line 1870 of file float.c.

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

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

◆ dcosd()

Datum dcosd ( PG_FUNCTION_ARGS  )

Definition at line 2319 of file float.c.

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

References cosd_q1(), ereport, errcode(), errmsg(), ERROR, 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 2628 of file float.c.

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

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

◆ dcot()

Datum dcot ( PG_FUNCTION_ARGS  )

Definition at line 1911 of file float.c.

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

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

◆ dcotd()

Datum dcotd ( PG_FUNCTION_ARGS  )

Definition at line 2374 of file float.c.

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

References cosd_q1(), cot_45, ereport, errcode(), errmsg(), ERROR, 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 2562 of file float.c.

2563 {
2564  float8 arg1 = PG_GETARG_FLOAT8(0);
2565 
2567 }
static float8 float8_div(const float8 val1, const float8 val2)
Definition: float.h:238

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

Referenced by degtorad().

◆ derf()

Datum derf ( PG_FUNCTION_ARGS  )

Definition at line 2753 of file float.c.

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

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

◆ derfc()

Datum derfc ( PG_FUNCTION_ARGS  )

Definition at line 2773 of file float.c.

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

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

◆ dexp()

Datum dexp ( PG_FUNCTION_ARGS  )

Definition at line 1645 of file float.c.

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

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

◆ dfloor()

Datum dfloor ( PG_FUNCTION_ARGS  )

Definition at line 1393 of file float.c.

1394 {
1395  float8 arg1 = PG_GETARG_FLOAT8(0);
1396 
1397  PG_RETURN_FLOAT8(floor(arg1));
1398 }

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dlog1()

Datum dlog1 ( PG_FUNCTION_ARGS  )

Definition at line 1691 of file float.c.

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

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

◆ dlog10()

Datum dlog10 ( PG_FUNCTION_ARGS  )

Definition at line 1723 of file float.c.

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

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

◆ dpi()

Definition at line 2574 of file float.c.

2575 {
2577 }
#define M_PI
Definition: earthdistance.c:11

References M_PI, and PG_RETURN_FLOAT8.

◆ dpow()

Datum dpow ( PG_FUNCTION_ARGS  )

Definition at line 1490 of file float.c.

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

References ereport, errcode(), errmsg(), ERROR, 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 1369 of file float.c.

1370 {
1371  float8 arg1 = PG_GETARG_FLOAT8(0);
1372 
1373  PG_RETURN_FLOAT8(rint(arg1));
1374 }

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsign()

Datum dsign ( PG_FUNCTION_ARGS  )

Definition at line 1406 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsin()

Datum dsin ( PG_FUNCTION_ARGS  )

Definition at line 1939 of file float.c.

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

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

◆ dsind()

Datum dsind ( PG_FUNCTION_ARGS  )

Definition at line 2440 of file float.c.

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

References ereport, errcode(), errmsg(), ERROR, 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 2599 of file float.c.

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

References get_float8_infinity(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsqrt()

Datum dsqrt ( PG_FUNCTION_ARGS  )

Definition at line 1447 of file float.c.

1448 {
1449  float8 arg1 = PG_GETARG_FLOAT8(0);
1450  float8 result;
1451 
1452  if (arg1 < 0)
1453  ereport(ERROR,
1454  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
1455  errmsg("cannot take square root of a negative number")));
1456 
1457  result = sqrt(arg1);
1458  if (unlikely(isinf(result)) && !isinf(arg1))
1460  if (unlikely(result == 0.0) && arg1 != 0.0)
1462 
1463  PG_RETURN_FLOAT8(result);
1464 }

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

◆ dtan()

Datum dtan ( PG_FUNCTION_ARGS  )

Definition at line 1966 of file float.c.

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

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

◆ dtand()

Datum dtand ( PG_FUNCTION_ARGS  )

Definition at line 2496 of file float.c.

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

References cosd_q1(), ereport, errcode(), errmsg(), ERROR, 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 2653 of file float.c.

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

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

◆ dtof()

Datum dtof ( PG_FUNCTION_ARGS  )

Definition at line 1196 of file float.c.

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

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

◆ dtoi2()

Datum dtoi2 ( PG_FUNCTION_ARGS  )

Definition at line 1240 of file float.c.

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

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

◆ dtoi4()

Datum dtoi4 ( PG_FUNCTION_ARGS  )

Definition at line 1215 of file float.c.

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

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

◆ dtrunc()

Datum dtrunc ( PG_FUNCTION_ARGS  )

Definition at line 1429 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float48div()

Datum float48div ( PG_FUNCTION_ARGS  )

Definition at line 3812 of file float.c.

3813 {
3814  float4 arg1 = PG_GETARG_FLOAT4(0);
3815  float8 arg2 = PG_GETARG_FLOAT8(1);
3816 
3817  PG_RETURN_FLOAT8(float8_div((float8) arg1, arg2));
3818 }

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

◆ float48eq()

Datum float48eq ( PG_FUNCTION_ARGS  )

Definition at line 3872 of file float.c.

3873 {
3874  float4 arg1 = PG_GETARG_FLOAT4(0);
3875  float8 arg2 = PG_GETARG_FLOAT8(1);
3876 
3877  PG_RETURN_BOOL(float8_eq((float8) arg1, arg2));
3878 }
static bool float8_eq(const float8 val1, const float8 val2)
Definition: float.h:268
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

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

◆ float48ge()

Datum float48ge ( PG_FUNCTION_ARGS  )

Definition at line 3917 of file float.c.

3918 {
3919  float4 arg1 = PG_GETARG_FLOAT4(0);
3920  float8 arg2 = PG_GETARG_FLOAT8(1);
3921 
3922  PG_RETURN_BOOL(float8_ge((float8) arg1, arg2));
3923 }
static bool float8_ge(const float8 val1, const float8 val2)
Definition: float.h:328

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

◆ float48gt()

Datum float48gt ( PG_FUNCTION_ARGS  )

Definition at line 3908 of file float.c.

3909 {
3910  float4 arg1 = PG_GETARG_FLOAT4(0);
3911  float8 arg2 = PG_GETARG_FLOAT8(1);
3912 
3913  PG_RETURN_BOOL(float8_gt((float8) arg1, arg2));
3914 }
static bool float8_gt(const float8 val1, const float8 val2)
Definition: float.h:316

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

◆ float48le()

Datum float48le ( PG_FUNCTION_ARGS  )

Definition at line 3899 of file float.c.

3900 {
3901  float4 arg1 = PG_GETARG_FLOAT4(0);
3902  float8 arg2 = PG_GETARG_FLOAT8(1);
3903 
3904  PG_RETURN_BOOL(float8_le((float8) arg1, arg2));
3905 }
static bool float8_le(const float8 val1, const float8 val2)
Definition: float.h:304

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

◆ float48lt()

Datum float48lt ( PG_FUNCTION_ARGS  )

Definition at line 3890 of file float.c.

3891 {
3892  float4 arg1 = PG_GETARG_FLOAT4(0);
3893  float8 arg2 = PG_GETARG_FLOAT8(1);
3894 
3895  PG_RETURN_BOOL(float8_lt((float8) arg1, arg2));
3896 }
static bool float8_lt(const float8 val1, const float8 val2)
Definition: float.h:292

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

◆ float48mi()

Datum float48mi ( PG_FUNCTION_ARGS  )

Definition at line 3794 of file float.c.

3795 {
3796  float4 arg1 = PG_GETARG_FLOAT4(0);
3797  float8 arg2 = PG_GETARG_FLOAT8(1);
3798 
3799  PG_RETURN_FLOAT8(float8_mi((float8) arg1, arg2));
3800 }
static float8 float8_mi(const float8 val1, const float8 val2)
Definition: float.h:182

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

◆ float48mul()

Datum float48mul ( PG_FUNCTION_ARGS  )

Definition at line 3803 of file float.c.

3804 {
3805  float4 arg1 = PG_GETARG_FLOAT4(0);
3806  float8 arg2 = PG_GETARG_FLOAT8(1);
3807 
3808  PG_RETURN_FLOAT8(float8_mul((float8) arg1, arg2));
3809 }
static float8 float8_mul(const float8 val1, const float8 val2)
Definition: float.h:208

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

◆ float48ne()

Datum float48ne ( PG_FUNCTION_ARGS  )

Definition at line 3881 of file float.c.

3882 {
3883  float4 arg1 = PG_GETARG_FLOAT4(0);
3884  float8 arg2 = PG_GETARG_FLOAT8(1);
3885 
3886  PG_RETURN_BOOL(float8_ne((float8) arg1, arg2));
3887 }
static bool float8_ne(const float8 val1, const float8 val2)
Definition: float.h:280

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

◆ float48pl()

Datum float48pl ( PG_FUNCTION_ARGS  )

Definition at line 3785 of file float.c.

3786 {
3787  float4 arg1 = PG_GETARG_FLOAT4(0);
3788  float8 arg2 = PG_GETARG_FLOAT8(1);
3789 
3790  PG_RETURN_FLOAT8(float8_pl((float8) arg1, arg2));
3791 }
static float8 float8_pl(const float8 val1, const float8 val2)
Definition: float.h:158

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

◆ float4_accum()

Datum float4_accum ( PG_FUNCTION_ARGS  )

Definition at line 3041 of file float.c.

3042 {
3043  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3044 
3045  /* do computations as float8 */
3047  float8 *transvalues;
3048  float8 N,
3049  Sx,
3050  Sxx,
3051  tmp;
3052 
3053  transvalues = check_float8_array(transarray, "float4_accum", 3);
3054  N = transvalues[0];
3055  Sx = transvalues[1];
3056  Sxx = transvalues[2];
3057 
3058  /*
3059  * Use the Youngs-Cramer algorithm to incorporate the new value into the
3060  * transition values.
3061  */
3062  N += 1.0;
3063  Sx += newval;
3064  if (transvalues[0] > 0.0)
3065  {
3066  tmp = newval * N - Sx;
3067  Sxx += tmp * tmp / (N * transvalues[0]);
3068 
3069  /*
3070  * Overflow check. We only report an overflow error when finite
3071  * inputs lead to infinite results. Note also that Sxx should be NaN
3072  * if any of the inputs are infinite, so we intentionally prevent Sxx
3073  * from becoming infinite.
3074  */
3075  if (isinf(Sx) || isinf(Sxx))
3076  {
3077  if (!isinf(transvalues[1]) && !isinf(newval))
3079 
3080  Sxx = get_float8_nan();
3081  }
3082  }
3083  else
3084  {
3085  /*
3086  * At the first input, we normally can leave Sxx as 0. However, if
3087  * the first input is Inf or NaN, we'd better force Sxx to NaN;
3088  * otherwise we will falsely report variance zero when there are no
3089  * more inputs.
3090  */
3091  if (isnan(newval) || isinf(newval))
3092  Sxx = get_float8_nan();
3093  }
3094 
3095  /*
3096  * If we're invoked as an aggregate, we can cheat and modify our first
3097  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3098  * new array with the updated transition data and return it.
3099  */
3100  if (AggCheckCallContext(fcinfo, NULL))
3101  {
3102  transvalues[0] = N;
3103  transvalues[1] = Sx;
3104  transvalues[2] = Sxx;
3105 
3106  PG_RETURN_ARRAYTYPE_P(transarray);
3107  }
3108  else
3109  {
3110  Datum transdatums[3];
3111  ArrayType *result;
3112 
3113  transdatums[0] = Float8GetDatumFast(N);
3114  transdatums[1] = Float8GetDatumFast(Sx);
3115  transdatums[2] = Float8GetDatumFast(Sxx);
3116 
3117  result = construct_array(transdatums, 3,
3118  FLOAT8OID,
3119  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3120 
3121  PG_RETURN_ARRAYTYPE_P(result);
3122  }
3123 }
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:265
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3361
#define FLOAT8PASSBYVAL
Definition: c.h:635
static float8 * check_float8_array(ArrayType *transarray, const char *caller, int n)
Definition: float.c:2840
#define newval
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4511
uintptr_t Datum
Definition: postgres.h:64
#define Float8GetDatumFast(X)
Definition: postgres.h:556

References AggCheckCallContext(), check_float8_array(), construct_array(), Float8GetDatumFast, FLOAT8PASSBYVAL, 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 817 of file float.c.

818 {
819  if (float4_gt(a, b))
820  return 1;
821  if (float4_lt(a, b))
822  return -1;
823  return 0;
824 }
static bool float4_lt(const float4 val1, const float4 val2)
Definition: float.h:286
static bool float4_gt(const float4 val1, const float4 val2)
Definition: float.h:310
int b
Definition: isn.c:70
int a
Definition: isn.c:69

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

Referenced by btfloat4cmp(), and btfloat4fastcmp().

◆ float4abs()

Datum float4abs ( PG_FUNCTION_ARGS  )

Definition at line 592 of file float.c.

593 {
594  float4 arg1 = PG_GETARG_FLOAT4(0);
595 
596  PG_RETURN_FLOAT4(fabsf(arg1));
597 }

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4div()

Datum float4div ( PG_FUNCTION_ARGS  )

Definition at line 756 of file float.c.

757 {
758  float4 arg1 = PG_GETARG_FLOAT4(0);
759  float4 arg2 = PG_GETARG_FLOAT4(1);
760 
761  PG_RETURN_FLOAT4(float4_div(arg1, arg2));
762 }
static float4 float4_div(const float4 val1, const float4 val2)
Definition: float.h:222

References float4_div(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4eq()

Datum float4eq ( PG_FUNCTION_ARGS  )

Definition at line 827 of file float.c.

828 {
829  float4 arg1 = PG_GETARG_FLOAT4(0);
830  float4 arg2 = PG_GETARG_FLOAT4(1);
831 
832  PG_RETURN_BOOL(float4_eq(arg1, arg2));
833 }
static bool float4_eq(const float4 val1, const float4 val2)
Definition: float.h:262

References float4_eq(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4ge()

Datum float4ge ( PG_FUNCTION_ARGS  )

Definition at line 872 of file float.c.

873 {
874  float4 arg1 = PG_GETARG_FLOAT4(0);
875  float4 arg2 = PG_GETARG_FLOAT4(1);
876 
877  PG_RETURN_BOOL(float4_ge(arg1, arg2));
878 }
static bool float4_ge(const float4 val1, const float4 val2)
Definition: float.h:322

References float4_ge(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4gt()

Datum float4gt ( PG_FUNCTION_ARGS  )

Definition at line 863 of file float.c.

864 {
865  float4 arg1 = PG_GETARG_FLOAT4(0);
866  float4 arg2 = PG_GETARG_FLOAT4(1);
867 
868  PG_RETURN_BOOL(float4_gt(arg1, arg2));
869 }

References float4_gt(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4in()

Datum float4in ( PG_FUNCTION_ARGS  )

Definition at line 165 of file float.c.

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

References float4in_internal(), PG_GETARG_CSTRING, and PG_RETURN_FLOAT4.

Referenced by numeric_float4().

◆ float4in_internal()

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

Definition at line 184 of file float.c.

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

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

Referenced by float4in().

◆ float4larger()

Datum float4larger ( PG_FUNCTION_ARGS  )

Definition at line 621 of file float.c.

622 {
623  float4 arg1 = PG_GETARG_FLOAT4(0);
624  float4 arg2 = PG_GETARG_FLOAT4(1);
625  float4 result;
626 
627  if (float4_gt(arg1, arg2))
628  result = arg1;
629  else
630  result = arg2;
631  PG_RETURN_FLOAT4(result);
632 }

References float4_gt(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4le()

Datum float4le ( PG_FUNCTION_ARGS  )

Definition at line 854 of file float.c.

855 {
856  float4 arg1 = PG_GETARG_FLOAT4(0);
857  float4 arg2 = PG_GETARG_FLOAT4(1);
858 
859  PG_RETURN_BOOL(float4_le(arg1, arg2));
860 }
static bool float4_le(const float4 val1, const float4 val2)
Definition: float.h:298

References float4_le(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4lt()

Datum float4lt ( PG_FUNCTION_ARGS  )

Definition at line 845 of file float.c.

846 {
847  float4 arg1 = PG_GETARG_FLOAT4(0);
848  float4 arg2 = PG_GETARG_FLOAT4(1);
849 
850  PG_RETURN_BOOL(float4_lt(arg1, arg2));
851 }

References float4_lt(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4mi()

Datum float4mi ( PG_FUNCTION_ARGS  )

Definition at line 738 of file float.c.

739 {
740  float4 arg1 = PG_GETARG_FLOAT4(0);
741  float4 arg2 = PG_GETARG_FLOAT4(1);
742 
743  PG_RETURN_FLOAT4(float4_mi(arg1, arg2));
744 }
static float4 float4_mi(const float4 val1, const float4 val2)
Definition: float.h:170

References float4_mi(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4mul()

Datum float4mul ( PG_FUNCTION_ARGS  )

Definition at line 747 of file float.c.

748 {
749  float4 arg1 = PG_GETARG_FLOAT4(0);
750  float4 arg2 = PG_GETARG_FLOAT4(1);
751 
752  PG_RETURN_FLOAT4(float4_mul(arg1, arg2));
753 }
static float4 float4_mul(const float4 val1, const float4 val2)
Definition: float.h:194

References float4_mul(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4ne()

Datum float4ne ( PG_FUNCTION_ARGS  )

Definition at line 836 of file float.c.

837 {
838  float4 arg1 = PG_GETARG_FLOAT4(0);
839  float4 arg2 = PG_GETARG_FLOAT4(1);
840 
841  PG_RETURN_BOOL(float4_ne(arg1, arg2));
842 }
static bool float4_ne(const float4 val1, const float4 val2)
Definition: float.h:274

References float4_ne(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4out()

Datum float4out ( PG_FUNCTION_ARGS  )

Definition at line 320 of file float.c.

321 {
322  float4 num = PG_GETARG_FLOAT4(0);
323  char *ascii = (char *) palloc(32);
324  int ndig = FLT_DIG + extra_float_digits;
325 
326  if (extra_float_digits > 0)
327  {
330  }
331 
332  (void) pg_strfromd(ascii, 32, ndig, num);
334 }
int float_to_shortest_decimal_buf(float f, char *result)
Definition: f2s.c:780
int extra_float_digits
Definition: float.c:41
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
void * palloc(Size size)
Definition: mcxt.c:1317
Datum ascii(PG_FUNCTION_ARGS)
int pg_strfromd(char *str, size_t count, int precision, double value)
Definition: snprintf.c:1285

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

◆ float4pl()

Datum float4pl ( PG_FUNCTION_ARGS  )

Definition at line 729 of file float.c.

730 {
731  float4 arg1 = PG_GETARG_FLOAT4(0);
732  float4 arg2 = PG_GETARG_FLOAT4(1);
733 
734  PG_RETURN_FLOAT4(float4_pl(arg1, arg2));
735 }
static float4 float4_pl(const float4 val1, const float4 val2)
Definition: float.h:146

References float4_pl(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4recv()

Datum float4recv ( PG_FUNCTION_ARGS  )

Definition at line 340 of file float.c.

341 {
343 
345 }
static char * buf
Definition: pg_test_fsync.c:73
float4 pq_getmsgfloat4(StringInfo msg)
Definition: pqformat.c:469
StringInfoData * StringInfo
Definition: stringinfo.h:54

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

◆ float4send()

Datum float4send ( PG_FUNCTION_ARGS  )

Definition at line 351 of file float.c.

352 {
353  float4 num = PG_GETARG_FLOAT4(0);
355 
357  pq_sendfloat4(&buf, num);
359 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
void pq_sendfloat4(StringInfo buf, float4 f)
Definition: pqformat.c:252
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346

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

636 {
637  float4 arg1 = PG_GETARG_FLOAT4(0);
638  float4 arg2 = PG_GETARG_FLOAT4(1);
639  float4 result;
640 
641  if (float4_lt(arg1, arg2))
642  result = arg1;
643  else
644  result = arg2;
645  PG_RETURN_FLOAT4(result);
646 }

References float4_lt(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4um()

Datum float4um ( PG_FUNCTION_ARGS  )

Definition at line 603 of file float.c.

604 {
605  float4 arg1 = PG_GETARG_FLOAT4(0);
606  float4 result;
607 
608  result = -arg1;
609  PG_RETURN_FLOAT4(result);
610 }

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4up()

Datum float4up ( PG_FUNCTION_ARGS  )

Definition at line 613 of file float.c.

614 {
616 
618 }
void * arg

References arg, PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float84div()

Datum float84div ( PG_FUNCTION_ARGS  )

Definition at line 3854 of file float.c.

3855 {
3856  float8 arg1 = PG_GETARG_FLOAT8(0);
3857  float4 arg2 = PG_GETARG_FLOAT4(1);
3858 
3859  PG_RETURN_FLOAT8(float8_div(arg1, (float8) arg2));
3860 }

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

◆ float84eq()

Datum float84eq ( PG_FUNCTION_ARGS  )

Definition at line 3929 of file float.c.

3930 {
3931  float8 arg1 = PG_GETARG_FLOAT8(0);
3932  float4 arg2 = PG_GETARG_FLOAT4(1);
3933 
3934  PG_RETURN_BOOL(float8_eq(arg1, (float8) arg2));
3935 }

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

◆ float84ge()

Datum float84ge ( PG_FUNCTION_ARGS  )

Definition at line 3974 of file float.c.

3975 {
3976  float8 arg1 = PG_GETARG_FLOAT8(0);
3977  float4 arg2 = PG_GETARG_FLOAT4(1);
3978 
3979  PG_RETURN_BOOL(float8_ge(arg1, (float8) arg2));
3980 }

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

◆ float84gt()

Datum float84gt ( PG_FUNCTION_ARGS  )

Definition at line 3965 of file float.c.

3966 {
3967  float8 arg1 = PG_GETARG_FLOAT8(0);
3968  float4 arg2 = PG_GETARG_FLOAT4(1);
3969 
3970  PG_RETURN_BOOL(float8_gt(arg1, (float8) arg2));
3971 }

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

◆ float84le()

Datum float84le ( PG_FUNCTION_ARGS  )

Definition at line 3956 of file float.c.

3957 {
3958  float8 arg1 = PG_GETARG_FLOAT8(0);
3959  float4 arg2 = PG_GETARG_FLOAT4(1);
3960 
3961  PG_RETURN_BOOL(float8_le(arg1, (float8) arg2));
3962 }

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

◆ float84lt()

Datum float84lt ( PG_FUNCTION_ARGS  )

Definition at line 3947 of file float.c.

3948 {
3949  float8 arg1 = PG_GETARG_FLOAT8(0);
3950  float4 arg2 = PG_GETARG_FLOAT4(1);
3951 
3952  PG_RETURN_BOOL(float8_lt(arg1, (float8) arg2));
3953 }

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

◆ float84mi()

Datum float84mi ( PG_FUNCTION_ARGS  )

Definition at line 3836 of file float.c.

3837 {
3838  float8 arg1 = PG_GETARG_FLOAT8(0);
3839  float4 arg2 = PG_GETARG_FLOAT4(1);
3840 
3841  PG_RETURN_FLOAT8(float8_mi(arg1, (float8) arg2));
3842 }

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

◆ float84mul()

Datum float84mul ( PG_FUNCTION_ARGS  )

Definition at line 3845 of file float.c.

3846 {
3847  float8 arg1 = PG_GETARG_FLOAT8(0);
3848  float4 arg2 = PG_GETARG_FLOAT4(1);
3849 
3850  PG_RETURN_FLOAT8(float8_mul(arg1, (float8) arg2));
3851 }

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

◆ float84ne()

Datum float84ne ( PG_FUNCTION_ARGS  )

Definition at line 3938 of file float.c.

3939 {
3940  float8 arg1 = PG_GETARG_FLOAT8(0);
3941  float4 arg2 = PG_GETARG_FLOAT4(1);
3942 
3943  PG_RETURN_BOOL(float8_ne(arg1, (float8) arg2));
3944 }

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

◆ float84pl()

Datum float84pl ( PG_FUNCTION_ARGS  )

Definition at line 3827 of file float.c.

3828 {
3829  float8 arg1 = PG_GETARG_FLOAT8(0);
3830  float4 arg2 = PG_GETARG_FLOAT4(1);
3831 
3832  PG_RETURN_FLOAT8(float8_pl(arg1, (float8) arg2));
3833 }

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

◆ float8_accum()

Datum float8_accum ( PG_FUNCTION_ARGS  )

Definition at line 2958 of file float.c.

2959 {
2960  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2962  float8 *transvalues;
2963  float8 N,
2964  Sx,
2965  Sxx,
2966  tmp;
2967 
2968  transvalues = check_float8_array(transarray, "float8_accum", 3);
2969  N = transvalues[0];
2970  Sx = transvalues[1];
2971  Sxx = transvalues[2];
2972 
2973  /*
2974  * Use the Youngs-Cramer algorithm to incorporate the new value into the
2975  * transition values.
2976  */
2977  N += 1.0;
2978  Sx += newval;
2979  if (transvalues[0] > 0.0)
2980  {
2981  tmp = newval * N - Sx;
2982  Sxx += tmp * tmp / (N * transvalues[0]);
2983 
2984  /*
2985  * Overflow check. We only report an overflow error when finite
2986  * inputs lead to infinite results. Note also that Sxx should be NaN
2987  * if any of the inputs are infinite, so we intentionally prevent Sxx
2988  * from becoming infinite.
2989  */
2990  if (isinf(Sx) || isinf(Sxx))
2991  {
2992  if (!isinf(transvalues[1]) && !isinf(newval))
2994 
2995  Sxx = get_float8_nan();
2996  }
2997  }
2998  else
2999  {
3000  /*
3001  * At the first input, we normally can leave Sxx as 0. However, if
3002  * the first input is Inf or NaN, we'd better force Sxx to NaN;
3003  * otherwise we will falsely report variance zero when there are no
3004  * more inputs.
3005  */
3006  if (isnan(newval) || isinf(newval))
3007  Sxx = get_float8_nan();
3008  }
3009 
3010  /*
3011  * If we're invoked as an aggregate, we can cheat and modify our first
3012  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3013  * new array with the updated transition data and return it.
3014  */
3015  if (AggCheckCallContext(fcinfo, NULL))
3016  {
3017  transvalues[0] = N;
3018  transvalues[1] = Sx;
3019  transvalues[2] = Sxx;
3020 
3021  PG_RETURN_ARRAYTYPE_P(transarray);
3022  }
3023  else
3024  {
3025  Datum transdatums[3];
3026  ArrayType *result;
3027 
3028  transdatums[0] = Float8GetDatumFast(N);
3029  transdatums[1] = Float8GetDatumFast(Sx);
3030  transdatums[2] = Float8GetDatumFast(Sxx);
3031 
3032  result = construct_array(transdatums, 3,
3033  FLOAT8OID,
3034  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3035 
3036  PG_RETURN_ARRAYTYPE_P(result);
3037  }
3038 }

References AggCheckCallContext(), check_float8_array(), construct_array(), Float8GetDatumFast, FLOAT8PASSBYVAL, 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 3126 of file float.c.

3127 {
3128  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3129  float8 *transvalues;
3130  float8 N,
3131  Sx;
3132 
3133  transvalues = check_float8_array(transarray, "float8_avg", 3);
3134  N = transvalues[0];
3135  Sx = transvalues[1];
3136  /* ignore Sxx */
3137 
3138  /* SQL defines AVG of no values to be NULL */
3139  if (N == 0.0)
3140  PG_RETURN_NULL();
3141 
3142  PG_RETURN_FLOAT8(Sx / N);
3143 }
#define PG_RETURN_NULL()
Definition: fmgr.h:345

References check_float8_array(), 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 911 of file float.c.

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

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

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

◆ float8_combine()

Datum float8_combine ( PG_FUNCTION_ARGS  )

Definition at line 2864 of file float.c.

2865 {
2866  ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
2867  ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
2868  float8 *transvalues1;
2869  float8 *transvalues2;
2870  float8 N1,
2871  Sx1,
2872  Sxx1,
2873  N2,
2874  Sx2,
2875  Sxx2,
2876  tmp,
2877  N,
2878  Sx,
2879  Sxx;
2880 
2881  transvalues1 = check_float8_array(transarray1, "float8_combine", 3);
2882  transvalues2 = check_float8_array(transarray2, "float8_combine", 3);
2883 
2884  N1 = transvalues1[0];
2885  Sx1 = transvalues1[1];
2886  Sxx1 = transvalues1[2];
2887 
2888  N2 = transvalues2[0];
2889  Sx2 = transvalues2[1];
2890  Sxx2 = transvalues2[2];
2891 
2892  /*--------------------
2893  * The transition values combine using a generalization of the
2894  * Youngs-Cramer algorithm as follows:
2895  *
2896  * N = N1 + N2
2897  * Sx = Sx1 + Sx2
2898  * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N;
2899  *
2900  * It's worth handling the special cases N1 = 0 and N2 = 0 separately
2901  * since those cases are trivial, and we then don't need to worry about
2902  * division-by-zero errors in the general case.
2903  *--------------------
2904  */
2905  if (N1 == 0.0)
2906  {
2907  N = N2;
2908  Sx = Sx2;
2909  Sxx = Sxx2;
2910  }
2911  else if (N2 == 0.0)
2912  {
2913  N = N1;
2914  Sx = Sx1;
2915  Sxx = Sxx1;
2916  }
2917  else
2918  {
2919  N = N1 + N2;
2920  Sx = float8_pl(Sx1, Sx2);
2921  tmp = Sx1 / N1 - Sx2 / N2;
2922  Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp * tmp / N;
2923  if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
2925  }
2926 
2927  /*
2928  * If we're invoked as an aggregate, we can cheat and modify our first
2929  * parameter in-place to reduce palloc overhead. Otherwise we construct a
2930  * new array with the updated transition data and return it.
2931  */
2932  if (AggCheckCallContext(fcinfo, NULL))
2933  {
2934  transvalues1[0] = N;
2935  transvalues1[1] = Sx;
2936  transvalues1[2] = Sxx;
2937 
2938  PG_RETURN_ARRAYTYPE_P(transarray1);
2939  }
2940  else
2941  {
2942  Datum transdatums[3];
2943  ArrayType *result;
2944 
2945  transdatums[0] = Float8GetDatumFast(N);
2946  transdatums[1] = Float8GetDatumFast(Sx);
2947  transdatums[2] = Float8GetDatumFast(Sxx);
2948 
2949  result = construct_array(transdatums, 3,
2950  FLOAT8OID,
2951  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
2952 
2953  PG_RETURN_ARRAYTYPE_P(result);
2954  }
2955 }

References AggCheckCallContext(), check_float8_array(), construct_array(), float8_pl(), Float8GetDatumFast, FLOAT8PASSBYVAL, float_overflow_error(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_ARRAYTYPE_P, and unlikely.

◆ float8_corr()

Datum float8_corr ( PG_FUNCTION_ARGS  )

Definition at line 3652 of file float.c.

3653 {
3654  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3655  float8 *transvalues;
3656  float8 N,
3657  Sxx,
3658  Syy,
3659  Sxy;
3660 
3661  transvalues = check_float8_array(transarray, "float8_corr", 6);
3662  N = transvalues[0];
3663  Sxx = transvalues[2];
3664  Syy = transvalues[4];
3665  Sxy = transvalues[5];
3666 
3667  /* if N is 0 we should return NULL */
3668  if (N < 1.0)
3669  PG_RETURN_NULL();
3670 
3671  /* Note that Sxx and Syy are guaranteed to be non-negative */
3672 
3673  /* per spec, return NULL for horizontal and vertical lines */
3674  if (Sxx == 0 || Syy == 0)
3675  PG_RETURN_NULL();
3676 
3677  PG_RETURN_FLOAT8(Sxy / sqrt(Sxx * Syy));
3678 }

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

◆ float8_covar_pop()

Datum float8_covar_pop ( PG_FUNCTION_ARGS  )

Definition at line 3614 of file float.c.

3615 {
3616  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3617  float8 *transvalues;
3618  float8 N,
3619  Sxy;
3620 
3621  transvalues = check_float8_array(transarray, "float8_covar_pop", 6);
3622  N = transvalues[0];
3623  Sxy = transvalues[5];
3624 
3625  /* if N is 0 we should return NULL */
3626  if (N < 1.0)
3627  PG_RETURN_NULL();
3628 
3629  PG_RETURN_FLOAT8(Sxy / N);
3630 }

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

◆ float8_covar_samp()

Datum float8_covar_samp ( PG_FUNCTION_ARGS  )

Definition at line 3633 of file float.c.

3634 {
3635  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3636  float8 *transvalues;
3637  float8 N,
3638  Sxy;
3639 
3640  transvalues = check_float8_array(transarray, "float8_covar_samp", 6);
3641  N = transvalues[0];
3642  Sxy = transvalues[5];
3643 
3644  /* if N is <= 1 we should return NULL */
3645  if (N < 2.0)
3646  PG_RETURN_NULL();
3647 
3648  PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3649 }

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

◆ float8_regr_accum()

Datum float8_regr_accum ( PG_FUNCTION_ARGS  )

Definition at line 3255 of file float.c.

3256 {
3257  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3258  float8 newvalY = PG_GETARG_FLOAT8(1);
3259  float8 newvalX = PG_GETARG_FLOAT8(2);
3260  float8 *transvalues;
3261  float8 N,
3262  Sx,
3263  Sxx,
3264  Sy,
3265  Syy,
3266  Sxy,
3267  tmpX,
3268  tmpY,
3269  scale;
3270 
3271  transvalues = check_float8_array(transarray, "float8_regr_accum", 6);
3272  N = transvalues[0];
3273  Sx = transvalues[1];
3274  Sxx = transvalues[2];
3275  Sy = transvalues[3];
3276  Syy = transvalues[4];
3277  Sxy = transvalues[5];
3278 
3279  /*
3280  * Use the Youngs-Cramer algorithm to incorporate the new values into the
3281  * transition values.
3282  */
3283  N += 1.0;
3284  Sx += newvalX;
3285  Sy += newvalY;
3286  if (transvalues[0] > 0.0)
3287  {
3288  tmpX = newvalX * N - Sx;
3289  tmpY = newvalY * N - Sy;
3290  scale = 1.0 / (N * transvalues[0]);
3291  Sxx += tmpX * tmpX * scale;
3292  Syy += tmpY * tmpY * scale;
3293  Sxy += tmpX * tmpY * scale;
3294 
3295  /*
3296  * Overflow check. We only report an overflow error when finite
3297  * inputs lead to infinite results. Note also that Sxx, Syy and Sxy
3298  * should be NaN if any of the relevant inputs are infinite, so we
3299  * intentionally prevent them from becoming infinite.
3300  */
3301  if (isinf(Sx) || isinf(Sxx) || isinf(Sy) || isinf(Syy) || isinf(Sxy))
3302  {
3303  if (((isinf(Sx) || isinf(Sxx)) &&
3304  !isinf(transvalues[1]) && !isinf(newvalX)) ||
3305  ((isinf(Sy) || isinf(Syy)) &&
3306  !isinf(transvalues[3]) && !isinf(newvalY)) ||
3307  (isinf(Sxy) &&
3308  !isinf(transvalues[1]) && !isinf(newvalX) &&
3309  !isinf(transvalues[3]) && !isinf(newvalY)))
3311 
3312  if (isinf(Sxx))
3313  Sxx = get_float8_nan();
3314  if (isinf(Syy))
3315  Syy = get_float8_nan();
3316  if (isinf(Sxy))
3317  Sxy = get_float8_nan();
3318  }
3319  }
3320  else
3321  {
3322  /*
3323  * At the first input, we normally can leave Sxx et al as 0. However,
3324  * if the first input is Inf or NaN, we'd better force the dependent
3325  * sums to NaN; otherwise we will falsely report variance zero when
3326  * there are no more inputs.
3327  */
3328  if (isnan(newvalX) || isinf(newvalX))
3329  Sxx = Sxy = get_float8_nan();
3330  if (isnan(newvalY) || isinf(newvalY))
3331  Syy = Sxy = get_float8_nan();
3332  }
3333 
3334  /*
3335  * If we're invoked as an aggregate, we can cheat and modify our first
3336  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3337  * new array with the updated transition data and return it.
3338  */
3339  if (AggCheckCallContext(fcinfo, NULL))
3340  {
3341  transvalues[0] = N;
3342  transvalues[1] = Sx;
3343  transvalues[2] = Sxx;
3344  transvalues[3] = Sy;
3345  transvalues[4] = Syy;
3346  transvalues[5] = Sxy;
3347 
3348  PG_RETURN_ARRAYTYPE_P(transarray);
3349  }
3350  else
3351  {
3352  Datum transdatums[6];
3353  ArrayType *result;
3354 
3355  transdatums[0] = Float8GetDatumFast(N);
3356  transdatums[1] = Float8GetDatumFast(Sx);
3357  transdatums[2] = Float8GetDatumFast(Sxx);
3358  transdatums[3] = Float8GetDatumFast(Sy);
3359  transdatums[4] = Float8GetDatumFast(Syy);
3360  transdatums[5] = Float8GetDatumFast(Sxy);
3361 
3362  result = construct_array(transdatums, 6,
3363  FLOAT8OID,
3364  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3365 
3366  PG_RETURN_ARRAYTYPE_P(result);
3367  }
3368 }
static int scale
Definition: pgbench.c:181

References AggCheckCallContext(), check_float8_array(), construct_array(), Float8GetDatumFast, FLOAT8PASSBYVAL, 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 3576 of file float.c.

3577 {
3578  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3579  float8 *transvalues;
3580  float8 N,
3581  Sx;
3582 
3583  transvalues = check_float8_array(transarray, "float8_regr_avgx", 6);
3584  N = transvalues[0];
3585  Sx = transvalues[1];
3586 
3587  /* if N is 0 we should return NULL */
3588  if (N < 1.0)
3589  PG_RETURN_NULL();
3590 
3591  PG_RETURN_FLOAT8(Sx / N);
3592 }

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

◆ float8_regr_avgy()

Datum float8_regr_avgy ( PG_FUNCTION_ARGS  )

Definition at line 3595 of file float.c.

3596 {
3597  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3598  float8 *transvalues;
3599  float8 N,
3600  Sy;
3601 
3602  transvalues = check_float8_array(transarray, "float8_regr_avgy", 6);
3603  N = transvalues[0];
3604  Sy = transvalues[3];
3605 
3606  /* if N is 0 we should return NULL */
3607  if (N < 1.0)
3608  PG_RETURN_NULL();
3609 
3610  PG_RETURN_FLOAT8(Sy / N);
3611 }

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

◆ float8_regr_combine()

Datum float8_regr_combine ( PG_FUNCTION_ARGS  )

Definition at line 3379 of file float.c.

3380 {
3381  ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
3382  ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
3383  float8 *transvalues1;
3384  float8 *transvalues2;
3385  float8 N1,
3386  Sx1,
3387  Sxx1,
3388  Sy1,
3389  Syy1,
3390  Sxy1,
3391  N2,
3392  Sx2,
3393  Sxx2,
3394  Sy2,
3395  Syy2,
3396  Sxy2,
3397  tmp1,
3398  tmp2,
3399  N,
3400  Sx,
3401  Sxx,
3402  Sy,
3403  Syy,
3404  Sxy;
3405 
3406  transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 6);
3407  transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 6);
3408 
3409  N1 = transvalues1[0];
3410  Sx1 = transvalues1[1];
3411  Sxx1 = transvalues1[2];
3412  Sy1 = transvalues1[3];
3413  Syy1 = transvalues1[4];
3414  Sxy1 = transvalues1[5];
3415 
3416  N2 = transvalues2[0];
3417  Sx2 = transvalues2[1];
3418  Sxx2 = transvalues2[2];
3419  Sy2 = transvalues2[3];
3420  Syy2 = transvalues2[4];
3421  Sxy2 = transvalues2[5];
3422 
3423  /*--------------------
3424  * The transition values combine using a generalization of the
3425  * Youngs-Cramer algorithm as follows:
3426  *
3427  * N = N1 + N2
3428  * Sx = Sx1 + Sx2
3429  * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N
3430  * Sy = Sy1 + Sy2
3431  * Syy = Syy1 + Syy2 + N1 * N2 * (Sy1/N1 - Sy2/N2)^2 / N
3432  * Sxy = Sxy1 + Sxy2 + N1 * N2 * (Sx1/N1 - Sx2/N2) * (Sy1/N1 - Sy2/N2) / N
3433  *
3434  * It's worth handling the special cases N1 = 0 and N2 = 0 separately
3435  * since those cases are trivial, and we then don't need to worry about
3436  * division-by-zero errors in the general case.
3437  *--------------------
3438  */
3439  if (N1 == 0.0)
3440  {
3441  N = N2;
3442  Sx = Sx2;
3443  Sxx = Sxx2;
3444  Sy = Sy2;
3445  Syy = Syy2;
3446  Sxy = Sxy2;
3447  }
3448  else if (N2 == 0.0)
3449  {
3450  N = N1;
3451  Sx = Sx1;
3452  Sxx = Sxx1;
3453  Sy = Sy1;
3454  Syy = Syy1;
3455  Sxy = Sxy1;
3456  }
3457  else
3458  {
3459  N = N1 + N2;
3460  Sx = float8_pl(Sx1, Sx2);
3461  tmp1 = Sx1 / N1 - Sx2 / N2;
3462  Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp1 * tmp1 / N;
3463  if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3465  Sy = float8_pl(Sy1, Sy2);
3466  tmp2 = Sy1 / N1 - Sy2 / N2;
3467  Syy = Syy1 + Syy2 + N1 * N2 * tmp2 * tmp2 / N;
3468  if (unlikely(isinf(Syy)) && !isinf(Syy1) && !isinf(Syy2))
3470  Sxy = Sxy1 + Sxy2 + N1 * N2 * tmp1 * tmp2 / N;
3471  if (unlikely(isinf(Sxy)) && !isinf(Sxy1) && !isinf(Sxy2))
3473  }
3474 
3475  /*
3476  * If we're invoked as an aggregate, we can cheat and modify our first
3477  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3478  * new array with the updated transition data and return it.
3479  */
3480  if (AggCheckCallContext(fcinfo, NULL))
3481  {
3482  transvalues1[0] = N;
3483  transvalues1[1] = Sx;
3484  transvalues1[2] = Sxx;
3485  transvalues1[3] = Sy;
3486  transvalues1[4] = Syy;
3487  transvalues1[5] = Sxy;
3488 
3489  PG_RETURN_ARRAYTYPE_P(transarray1);
3490  }
3491  else
3492  {
3493  Datum transdatums[6];
3494  ArrayType *result;
3495 
3496  transdatums[0] = Float8GetDatumFast(N);
3497  transdatums[1] = Float8GetDatumFast(Sx);
3498  transdatums[2] = Float8GetDatumFast(Sxx);
3499  transdatums[3] = Float8GetDatumFast(Sy);
3500  transdatums[4] = Float8GetDatumFast(Syy);
3501  transdatums[5] = Float8GetDatumFast(Sxy);
3502 
3503  result = construct_array(transdatums, 6,
3504  FLOAT8OID,
3505  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3506 
3507  PG_RETURN_ARRAYTYPE_P(result);
3508  }
3509 }

References AggCheckCallContext(), check_float8_array(), construct_array(), float8_pl(), Float8GetDatumFast, FLOAT8PASSBYVAL, float_overflow_error(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_ARRAYTYPE_P, and unlikely.

◆ float8_regr_intercept()

Datum float8_regr_intercept ( PG_FUNCTION_ARGS  )

Definition at line 3741 of file float.c.

3742 {
3743  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3744  float8 *transvalues;
3745  float8 N,
3746  Sx,
3747  Sxx,
3748  Sy,
3749  Sxy;
3750 
3751  transvalues = check_float8_array(transarray, "float8_regr_intercept", 6);
3752  N = transvalues[0];
3753  Sx = transvalues[1];
3754  Sxx = transvalues[2];
3755  Sy = transvalues[3];
3756  Sxy = transvalues[5];
3757 
3758  /* if N is 0 we should return NULL */
3759  if (N < 1.0)
3760  PG_RETURN_NULL();
3761 
3762  /* Note that Sxx is guaranteed to be non-negative */
3763 
3764  /* per spec, return NULL for a vertical line */
3765  if (Sxx == 0)
3766  PG_RETURN_NULL();
3767 
3768  PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
3769 }

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

◆ float8_regr_r2()

Datum float8_regr_r2 ( PG_FUNCTION_ARGS  )

Definition at line 3681 of file float.c.

3682 {
3683  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3684  float8 *transvalues;
3685  float8 N,
3686  Sxx,
3687  Syy,
3688  Sxy;
3689 
3690  transvalues = check_float8_array(transarray, "float8_regr_r2", 6);
3691  N = transvalues[0];
3692  Sxx = transvalues[2];
3693  Syy = transvalues[4];
3694  Sxy = transvalues[5];
3695 
3696  /* if N is 0 we should return NULL */
3697  if (N < 1.0)
3698  PG_RETURN_NULL();
3699 
3700  /* Note that Sxx and Syy are guaranteed to be non-negative */
3701 
3702  /* per spec, return NULL for a vertical line */
3703  if (Sxx == 0)
3704  PG_RETURN_NULL();
3705 
3706  /* per spec, return 1.0 for a horizontal line */
3707  if (Syy == 0)
3708  PG_RETURN_FLOAT8(1.0);
3709 
3710  PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3711 }

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

◆ float8_regr_slope()

Datum float8_regr_slope ( PG_FUNCTION_ARGS  )

Definition at line 3714 of file float.c.

3715 {
3716  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3717  float8 *transvalues;
3718  float8 N,
3719  Sxx,
3720  Sxy;
3721 
3722  transvalues = check_float8_array(transarray, "float8_regr_slope", 6);
3723  N = transvalues[0];
3724  Sxx = transvalues[2];
3725  Sxy = transvalues[5];
3726 
3727  /* if N is 0 we should return NULL */
3728  if (N < 1.0)
3729  PG_RETURN_NULL();
3730 
3731  /* Note that Sxx is guaranteed to be non-negative */
3732 
3733  /* per spec, return NULL for a vertical line */
3734  if (Sxx == 0)
3735  PG_RETURN_NULL();
3736 
3737  PG_RETURN_FLOAT8(Sxy / Sxx);
3738 }

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

◆ float8_regr_sxx()

Datum float8_regr_sxx ( PG_FUNCTION_ARGS  )

Definition at line 3513 of file float.c.

3514 {
3515  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3516  float8 *transvalues;
3517  float8 N,
3518  Sxx;
3519 
3520  transvalues = check_float8_array(transarray, "float8_regr_sxx", 6);
3521  N = transvalues[0];
3522  Sxx = transvalues[2];
3523 
3524  /* if N is 0 we should return NULL */
3525  if (N < 1.0)
3526  PG_RETURN_NULL();
3527 
3528  /* Note that Sxx is guaranteed to be non-negative */
3529 
3530  PG_RETURN_FLOAT8(Sxx);
3531 }

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

◆ float8_regr_sxy()

Datum float8_regr_sxy ( PG_FUNCTION_ARGS  )

Definition at line 3555 of file float.c.

3556 {
3557  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3558  float8 *transvalues;
3559  float8 N,
3560  Sxy;
3561 
3562  transvalues = check_float8_array(transarray, "float8_regr_sxy", 6);
3563  N = transvalues[0];
3564  Sxy = transvalues[5];
3565 
3566  /* if N is 0 we should return NULL */
3567  if (N < 1.0)
3568  PG_RETURN_NULL();
3569 
3570  /* A negative result is valid here */
3571 
3572  PG_RETURN_FLOAT8(Sxy);
3573 }

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

◆ float8_regr_syy()

Datum float8_regr_syy ( PG_FUNCTION_ARGS  )

Definition at line 3534 of file float.c.

3535 {
3536  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3537  float8 *transvalues;
3538  float8 N,
3539  Syy;
3540 
3541  transvalues = check_float8_array(transarray, "float8_regr_syy", 6);
3542  N = transvalues[0];
3543  Syy = transvalues[4];
3544 
3545  /* if N is 0 we should return NULL */
3546  if (N < 1.0)
3547  PG_RETURN_NULL();
3548 
3549  /* Note that Syy is guaranteed to be non-negative */
3550 
3551  PG_RETURN_FLOAT8(Syy);
3552 }

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

◆ float8_stddev_pop()

Datum float8_stddev_pop ( PG_FUNCTION_ARGS  )

Definition at line 3190 of file float.c.

3191 {
3192  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3193  float8 *transvalues;
3194  float8 N,
3195  Sxx;
3196 
3197  transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
3198  N = transvalues[0];
3199  /* ignore Sx */
3200  Sxx = transvalues[2];
3201 
3202  /* Population stddev is undefined when N is 0, so return NULL */
3203  if (N == 0.0)
3204  PG_RETURN_NULL();
3205 
3206  /* Note that Sxx is guaranteed to be non-negative */
3207 
3208  PG_RETURN_FLOAT8(sqrt(Sxx / N));
3209 }

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

◆ float8_stddev_samp()

Datum float8_stddev_samp ( PG_FUNCTION_ARGS  )

Definition at line 3212 of file float.c.

3213 {
3214  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3215  float8 *transvalues;
3216  float8 N,
3217  Sxx;
3218 
3219  transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
3220  N = transvalues[0];
3221  /* ignore Sx */
3222  Sxx = transvalues[2];
3223 
3224  /* Sample stddev is undefined when N is 0 or 1, so return NULL */
3225  if (N <= 1.0)
3226  PG_RETURN_NULL();
3227 
3228  /* Note that Sxx is guaranteed to be non-negative */
3229 
3230  PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0)));
3231 }

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

◆ float8_var_pop()

Datum float8_var_pop ( PG_FUNCTION_ARGS  )

Definition at line 3146 of file float.c.

3147 {
3148  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3149  float8 *transvalues;
3150  float8 N,
3151  Sxx;
3152 
3153  transvalues = check_float8_array(transarray, "float8_var_pop", 3);
3154  N = transvalues[0];
3155  /* ignore Sx */
3156  Sxx = transvalues[2];
3157 
3158  /* Population variance is undefined when N is 0, so return NULL */
3159  if (N == 0.0)
3160  PG_RETURN_NULL();
3161 
3162  /* Note that Sxx is guaranteed to be non-negative */
3163 
3164  PG_RETURN_FLOAT8(Sxx / N);
3165 }

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

◆ float8_var_samp()

Datum float8_var_samp ( PG_FUNCTION_ARGS  )

Definition at line 3168 of file float.c.

3169 {
3170  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3171  float8 *transvalues;
3172  float8 N,
3173  Sxx;
3174 
3175  transvalues = check_float8_array(transarray, "float8_var_samp", 3);
3176  N = transvalues[0];
3177  /* ignore Sx */
3178  Sxx = transvalues[2];
3179 
3180  /* Sample variance is undefined when N is 0 or 1, so return NULL */
3181  if (N <= 1.0)
3182  PG_RETURN_NULL();
3183 
3184  /* Note that Sxx is guaranteed to be non-negative */
3185 
3186  PG_RETURN_FLOAT8(Sxx / (N - 1.0));
3187 }

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

◆ float8abs()

Datum float8abs ( PG_FUNCTION_ARGS  )

Definition at line 658 of file float.c.

659 {
660  float8 arg1 = PG_GETARG_FLOAT8(0);
661 
662  PG_RETURN_FLOAT8(fabs(arg1));
663 }

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8div()

Datum float8div ( PG_FUNCTION_ARGS  )

Definition at line 798 of file float.c.

799 {
800  float8 arg1 = PG_GETARG_FLOAT8(0);
801  float8 arg2 = PG_GETARG_FLOAT8(1);
802 
803  PG_RETURN_FLOAT8(float8_div(arg1, arg2));
804 }

References float8_div(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8eq()

Datum float8eq ( PG_FUNCTION_ARGS  )

Definition at line 921 of file float.c.

922 {
923  float8 arg1 = PG_GETARG_FLOAT8(0);
924  float8 arg2 = PG_GETARG_FLOAT8(1);
925 
926  PG_RETURN_BOOL(float8_eq(arg1, arg2));
927 }

References float8_eq(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8ge()

Datum float8ge ( PG_FUNCTION_ARGS  )

Definition at line 966 of file float.c.

967 {
968  float8 arg1 = PG_GETARG_FLOAT8(0);
969  float8 arg2 = PG_GETARG_FLOAT8(1);
970 
971  PG_RETURN_BOOL(float8_ge(arg1, arg2));
972 }

References float8_ge(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8gt()

Datum float8gt ( PG_FUNCTION_ARGS  )

Definition at line 957 of file float.c.

958 {
959  float8 arg1 = PG_GETARG_FLOAT8(0);
960  float8 arg2 = PG_GETARG_FLOAT8(1);
961 
962  PG_RETURN_BOOL(float8_gt(arg1, arg2));
963 }

References float8_gt(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8in()

Datum float8in ( PG_FUNCTION_ARGS  )

Definition at line 365 of file float.c.

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

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

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

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

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

◆ float8larger()

Datum float8larger ( PG_FUNCTION_ARGS  )

Definition at line 688 of file float.c.

689 {
690  float8 arg1 = PG_GETARG_FLOAT8(0);
691  float8 arg2 = PG_GETARG_FLOAT8(1);
692  float8 result;
693 
694  if (float8_gt(arg1, arg2))
695  result = arg1;
696  else
697  result = arg2;
698  PG_RETURN_FLOAT8(result);
699 }

References float8_gt(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8le()

Datum float8le ( PG_FUNCTION_ARGS  )

Definition at line 948 of file float.c.

949 {
950  float8 arg1 = PG_GETARG_FLOAT8(0);
951  float8 arg2 = PG_GETARG_FLOAT8(1);
952 
953  PG_RETURN_BOOL(float8_le(arg1, arg2));
954 }

References float8_le(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8lt()

Datum float8lt ( PG_FUNCTION_ARGS  )

Definition at line 939 of file float.c.

940 {
941  float8 arg1 = PG_GETARG_FLOAT8(0);
942  float8 arg2 = PG_GETARG_FLOAT8(1);
943 
944  PG_RETURN_BOOL(float8_lt(arg1, arg2));
945 }

References float8_lt(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8mi()

Datum float8mi ( PG_FUNCTION_ARGS  )

Definition at line 780 of file float.c.

781 {
782  float8 arg1 = PG_GETARG_FLOAT8(0);
783  float8 arg2 = PG_GETARG_FLOAT8(1);
784 
785  PG_RETURN_FLOAT8(float8_mi(arg1, arg2));
786 }

References float8_mi(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8mul()

Datum float8mul ( PG_FUNCTION_ARGS  )

Definition at line 789 of file float.c.

790 {
791  float8 arg1 = PG_GETARG_FLOAT8(0);
792  float8 arg2 = PG_GETARG_FLOAT8(1);
793 
794  PG_RETURN_FLOAT8(float8_mul(arg1, arg2));
795 }

References float8_mul(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8ne()

Datum float8ne ( PG_FUNCTION_ARGS  )

Definition at line 930 of file float.c.

931 {
932  float8 arg1 = PG_GETARG_FLOAT8(0);
933  float8 arg2 = PG_GETARG_FLOAT8(1);
934 
935  PG_RETURN_BOOL(float8_ne(arg1, arg2));
936 }

References float8_ne(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8out()

Datum float8out ( PG_FUNCTION_ARGS  )

Definition at line 523 of file float.c.

524 {
525  float8 num = PG_GETARG_FLOAT8(0);
526 
528 }
char * float8out_internal(double num)
Definition: float.c:538

References float8out_internal(), PG_GETARG_FLOAT8, and PG_RETURN_CSTRING.

◆ float8out_internal()

char* float8out_internal ( double  num)

Definition at line 538 of file float.c.

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

References ascii(), double_to_shortest_decimal_buf(), extra_float_digits, 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 771 of file float.c.

772 {
773  float8 arg1 = PG_GETARG_FLOAT8(0);
774  float8 arg2 = PG_GETARG_FLOAT8(1);
775 
776  PG_RETURN_FLOAT8(float8_pl(arg1, arg2));
777 }

References float8_pl(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8recv()

Datum float8recv ( PG_FUNCTION_ARGS  )

Definition at line 557 of file float.c.

558 {
560 
562 }
float8 pq_getmsgfloat8(StringInfo msg)
Definition: pqformat.c:488

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

◆ float8send()

Datum float8send ( PG_FUNCTION_ARGS  )

Definition at line 568 of file float.c.

569 {
570  float8 num = PG_GETARG_FLOAT8(0);
572 
574  pq_sendfloat8(&buf, num);
576 }
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 702 of file float.c.

703 {
704  float8 arg1 = PG_GETARG_FLOAT8(0);
705  float8 arg2 = PG_GETARG_FLOAT8(1);
706  float8 result;
707 
708  if (float8_lt(arg1, arg2))
709  result = arg1;
710  else
711  result = arg2;
712  PG_RETURN_FLOAT8(result);
713 }

References float8_lt(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8um()

Datum float8um ( PG_FUNCTION_ARGS  )

Definition at line 670 of file float.c.

671 {
672  float8 arg1 = PG_GETARG_FLOAT8(0);
673  float8 result;
674 
675  result = -arg1;
676  PG_RETURN_FLOAT8(result);
677 }

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8up()

Datum float8up ( PG_FUNCTION_ARGS  )

Definition at line 680 of file float.c.

681 {
683 
685 }

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

96 {
97  ereport(ERROR,
98  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
99  errmsg("value out of range: underflow")));
100 }

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

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

◆ float_zero_divide_error()

pg_noinline void float_zero_divide_error ( void  )

Definition at line 103 of file float.c.

104 {
105  ereport(ERROR,
106  (errcode(ERRCODE_DIVISION_BY_ZERO),
107  errmsg("division by zero")));
108 }

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

Referenced by float4_div(), and float8_div().

◆ ftod()

Datum ftod ( PG_FUNCTION_ARGS  )

Definition at line 1184 of file float.c.

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

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT8.

◆ ftoi2()

Datum ftoi2 ( PG_FUNCTION_ARGS  )

Definition at line 1314 of file float.c.

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

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

◆ ftoi4()

Datum ftoi4 ( PG_FUNCTION_ARGS  )

Definition at line 1289 of file float.c.

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

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

◆ i2tod()

Datum i2tod ( PG_FUNCTION_ARGS  )

Definition at line 1277 of file float.c.

1278 {
1279  int16 num = PG_GETARG_INT16(0);
1280 
1281  PG_RETURN_FLOAT8((float8) num);
1282 }
#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 1351 of file float.c.

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

References PG_GETARG_INT16, and PG_RETURN_FLOAT4.

◆ i4tod()

Datum i4tod ( PG_FUNCTION_ARGS  )

Definition at line 1265 of file float.c.

1266 {
1267  int32 num = PG_GETARG_INT32(0);
1268 
1269  PG_RETURN_FLOAT8((float8) num);
1270 }
#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 1339 of file float.c.

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

References PG_GETARG_INT32, and PG_RETURN_FLOAT4.

◆ in_range_float4_float8()

Datum in_range_float4_float8 ( PG_FUNCTION_ARGS  )

Definition at line 1104 of file float.c.

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

References ereport, errcode(), errmsg(), ERROR, 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 1028 of file float.c.

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

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

◆ init_degree_constants()

static void init_degree_constants ( void  )
static

Definition at line 2020 of file float.c.

2021 {
2024  asin_0_5 = asin(degree_c_one_half);
2025  acos_0_5 = acos(degree_c_one_half);
2026  atan_1_0 = atan(degree_c_one);
2029  degree_consts_set = true;
2030 }
float8 degree_c_sixty
Definition: float.c:69
float8 degree_c_thirty
Definition: float.c:67
float8 degree_c_forty_five
Definition: float.c:68
static float8 sin_30
Definition: float.c:45
float8 degree_c_one
Definition: float.c:71
float8 degree_c_one_half
Definition: float.c:70

References acos_0_5, asin_0_5, atan_1_0, cosd_q1(), cot_45, degree_c_forty_five, degree_c_one, degree_c_one_half, degree_c_sixty, degree_c_thirty, degree_consts_set, one_minus_cos_60, RADIANS_PER_DEGREE, sin_30, sind_q1(), and tan_45.

◆ is_infinite()

int is_infinite ( double  val)

Definition at line 119 of file float.c.

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

References val.

◆ radians()

Datum radians ( PG_FUNCTION_ARGS  )

Definition at line 2584 of file float.c.

2585 {
2586  float8 arg1 = PG_GETARG_FLOAT8(0);
2587 
2589 }

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

◆ sind_0_to_30()

static double sind_0_to_30 ( double  x)
static

Definition at line 2253 of file float.c.

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

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

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

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

3998 {
3999  float8 operand = PG_GETARG_FLOAT8(0);
4000  float8 bound1 = PG_GETARG_FLOAT8(1);
4001  float8 bound2 = PG_GETARG_FLOAT8(2);
4002  int32 count = PG_GETARG_INT32(3);
4003  int32 result;
4004 
4005  if (count <= 0)
4006  ereport(ERROR,
4007  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4008  errmsg("count must be greater than zero")));
4009 
4010  if (isnan(operand) || isnan(bound1) || isnan(bound2))
4011  ereport(ERROR,
4012  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4013  errmsg("operand, lower bound, and upper bound cannot be NaN")));
4014 
4015  /* Note that we allow "operand" to be infinite */
4016  if (isinf(bound1) || isinf(bound2))
4017  ereport(ERROR,
4018  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4019  errmsg("lower and upper bounds must be finite")));
4020 
4021  if (bound1 < bound2)
4022  {
4023  if (operand < bound1)
4024  result = 0;
4025  else if (operand >= bound2)
4026  {
4027  if (pg_add_s32_overflow(count, 1, &result))
4028  ereport(ERROR,
4029  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4030  errmsg("integer out of range")));
4031  }
4032  else
4033  {
4034  if (!isinf(bound2 - bound1))
4035  {
4036  /* The quotient is surely in [0,1], so this can't overflow */
4037  result = count * ((operand - bound1) / (bound2 - bound1));
4038  }
4039  else
4040  {
4041  /*
4042  * We get here if bound2 - bound1 overflows DBL_MAX. Since
4043  * both bounds are finite, their difference can't exceed twice
4044  * DBL_MAX; so we can perform the computation without overflow
4045  * by dividing all the inputs by 2. That should be exact too,
4046  * except in the case where a very small operand underflows to
4047  * zero, which would have negligible impact on the result
4048  * given such large bounds.
4049  */
4050  result = count * ((operand / 2 - bound1 / 2) / (bound2 / 2 - bound1 / 2));
4051  }
4052  /* The quotient could round to 1.0, which would be a lie */
4053  if (result >= count)
4054  result = count - 1;
4055  /* Having done that, we can add 1 without fear of overflow */
4056  result++;
4057  }
4058  }
4059  else if (bound1 > bound2)
4060  {
4061  if (operand > bound1)
4062  result = 0;
4063  else if (operand <= bound2)
4064  {
4065  if (pg_add_s32_overflow(count, 1, &result))
4066  ereport(ERROR,
4067  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4068  errmsg("integer out of range")));
4069  }
4070  else
4071  {
4072  if (!isinf(bound1 - bound2))
4073  result = count * ((bound1 - operand) / (bound1 - bound2));
4074  else
4075  result = count * ((bound1 / 2 - operand / 2) / (bound1 / 2 - bound2 / 2));
4076  if (result >= count)
4077  result = count - 1;
4078  result++;
4079  }
4080  }
4081  else
4082  {
4083  ereport(ERROR,
4084  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4085  errmsg("lower bound cannot equal upper bound")));
4086  result = 0; /* keep the compiler quiet */
4087  }
4088 
4089  PG_RETURN_INT32(result);
4090 }
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104

References ereport, errcode(), errmsg(), ERROR, 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 48 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 47 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 49 of file float.c.

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

◆ cot_45

float8 cot_45 = 0
static

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

Referenced by init_degree_constants().

◆ degree_c_one

float8 degree_c_one = 1.0

Definition at line 71 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_one_half

float8 degree_c_one_half = 0.5

Definition at line 70 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_sixty

float8 degree_c_sixty = 60.0

Definition at line 69 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_thirty

float8 degree_c_thirty = 30.0

Definition at line 67 of file float.c.

Referenced by init_degree_constants().

◆ degree_consts_set

bool degree_consts_set = false
static

Definition at line 44 of file float.c.

Referenced by init_degree_constants().

◆ extra_float_digits

int extra_float_digits = 1

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

Referenced by cosd_0_to_60(), and init_degree_constants().

◆ sin_30

float8 sin_30 = 0
static

Definition at line 45 of file float.c.

Referenced by init_degree_constants(), and sind_0_to_30().

◆ tan_45

float8 tan_45 = 0
static

Definition at line 50 of file float.c.

Referenced by dtand(), and init_degree_constants().