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/pg_prng.h"
#include "common/shortest_dec.h"
#include "libpq/pqformat.h"
#include "miscadmin.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 RETURN_ERROR(throw_error, have_error)
 
#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)
 
Datum float4out (PG_FUNCTION_ARGS)
 
Datum float4recv (PG_FUNCTION_ARGS)
 
Datum float4send (PG_FUNCTION_ARGS)
 
Datum float8in (PG_FUNCTION_ARGS)
 
double float8in_internal_opt_error (char *num, char **endptr_p, const char *type_name, const char *orig_string, bool *have_error)
 
double float8in_internal (char *num, char **endptr_p, const char *type_name, const char *orig_string)
 
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 drandom (PG_FUNCTION_ARGS)
 
Datum setseed (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
 
static bool drandom_seed_set = false
 
static pg_prng_state drandom_seed
 

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:46

Definition at line 2032 of file float.c.

◆ RETURN_ERROR

#define RETURN_ERROR (   throw_error,
  have_error 
)
Value:
do { \
if (have_error) { \
*have_error = true; \
return 0.0; \
} else { \
throw_error; \
} \
} while (0)

Definition at line 344 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:566
static float8 acos_0_5
Definition: float.c:50
static float8 asin_0_5
Definition: float.c:49
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:565
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:806

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:842

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

2853 {
2854  /*
2855  * We expect the input to be an N-element float array; verify that. We
2856  * don't need to use deconstruct_array() since the array data is just
2857  * going to look like a C array of N float8 values.
2858  */
2859  if (ARR_NDIM(transarray) != 1 ||
2860  ARR_DIMS(transarray)[0] != n ||
2861  ARR_HASNULL(transarray) ||
2862  ARR_ELEMTYPE(transarray) != FLOAT8OID)
2863  elog(ERROR, "%s: expected %d-element float8 array", caller, n);
2864  return (float8 *) ARR_DATA_PTR(transarray);
2865 }
#define ARR_NDIM(a)
Definition: array.h:283
#define ARR_DATA_PTR(a)
Definition: array.h:315
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_HASNULL(a)
Definition: array.h:284
#define ERROR
Definition: elog.h:35

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:48
#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:295
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define ereport(elevel,...)
Definition: elog.h:145
pg_noinline void float_overflow_error(void)
Definition: float.c:85
static float8 get_float8_nan(void)
Definition: float.h:122
#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:51

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:93

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:93

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:668

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:53
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:237

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

Referenced by degtorad().

◆ 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:10

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.

◆ drandom()

Datum drandom ( PG_FUNCTION_ARGS  )

Definition at line 2750 of file float.c.

2751 {
2752  float8 result;
2753 
2754  /* Initialize random seed, if not done yet in this process */
2755  if (unlikely(!drandom_seed_set))
2756  {
2757  /*
2758  * If possible, initialize the seed using high-quality random bits.
2759  * Should that fail for some reason, we fall back on a lower-quality
2760  * seed based on current time and PID.
2761  */
2763  {
2765  uint64 iseed;
2766 
2767  /* Mix the PID with the most predictable bits of the timestamp */
2768  iseed = (uint64) now ^ ((uint64) MyProcPid << 32);
2769  pg_prng_seed(&drandom_seed, iseed);
2770  }
2771  drandom_seed_set = true;
2772  }
2773 
2774  /* pg_prng_double produces desired result range [0.0 - 1.0) */
2775  result = pg_prng_double(&drandom_seed);
2776 
2777  PG_RETURN_FLOAT8(result);
2778 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1573
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1537
int64 TimestampTz
Definition: timestamp.h:39
static bool drandom_seed_set
Definition: float.c:68
static pg_prng_state drandom_seed
Definition: float.c:69
int MyProcPid
Definition: globals.c:44
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:226
void pg_prng_seed(pg_prng_state *state, uint64 seed)
Definition: pg_prng.c:83
#define pg_prng_strong_seed(state)
Definition: pg_prng.h:46

References drandom_seed, drandom_seed_set, GetCurrentTimestamp(), MyProcPid, now(), pg_prng_double(), pg_prng_seed(), pg_prng_strong_seed, 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:52

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:429
#define FLOAT8_FITS_IN_INT16(num)
Definition: c.h:1045
#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:1047
signed int int32
Definition: c.h:430

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

3825 {
3826  float4 arg1 = PG_GETARG_FLOAT4(0);
3827  float8 arg2 = PG_GETARG_FLOAT8(1);
3828 
3829  PG_RETURN_FLOAT8(float8_div((float8) arg1, arg2));
3830 }

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

◆ float48eq()

Datum float48eq ( PG_FUNCTION_ARGS  )

Definition at line 3884 of file float.c.

3885 {
3886  float4 arg1 = PG_GETARG_FLOAT4(0);
3887  float8 arg2 = PG_GETARG_FLOAT8(1);
3888 
3889  PG_RETURN_BOOL(float8_eq((float8) arg1, arg2));
3890 }
static bool float8_eq(const float8 val1, const float8 val2)
Definition: float.h:267
#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 3929 of file float.c.

3930 {
3931  float4 arg1 = PG_GETARG_FLOAT4(0);
3932  float8 arg2 = PG_GETARG_FLOAT8(1);
3933 
3934  PG_RETURN_BOOL(float8_ge((float8) arg1, arg2));
3935 }
static bool float8_ge(const float8 val1, const float8 val2)
Definition: float.h:327

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

◆ float48gt()

Datum float48gt ( PG_FUNCTION_ARGS  )

Definition at line 3920 of file float.c.

3921 {
3922  float4 arg1 = PG_GETARG_FLOAT4(0);
3923  float8 arg2 = PG_GETARG_FLOAT8(1);
3924 
3925  PG_RETURN_BOOL(float8_gt((float8) arg1, arg2));
3926 }
static bool float8_gt(const float8 val1, const float8 val2)
Definition: float.h:315

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

◆ float48le()

Datum float48le ( PG_FUNCTION_ARGS  )

Definition at line 3911 of file float.c.

3912 {
3913  float4 arg1 = PG_GETARG_FLOAT4(0);
3914  float8 arg2 = PG_GETARG_FLOAT8(1);
3915 
3916  PG_RETURN_BOOL(float8_le((float8) arg1, arg2));
3917 }
static bool float8_le(const float8 val1, const float8 val2)
Definition: float.h:303

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

◆ float48lt()

Datum float48lt ( PG_FUNCTION_ARGS  )

Definition at line 3902 of file float.c.

3903 {
3904  float4 arg1 = PG_GETARG_FLOAT4(0);
3905  float8 arg2 = PG_GETARG_FLOAT8(1);
3906 
3907  PG_RETURN_BOOL(float8_lt((float8) arg1, arg2));
3908 }
static bool float8_lt(const float8 val1, const float8 val2)
Definition: float.h:291

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

◆ float48mi()

Datum float48mi ( PG_FUNCTION_ARGS  )

Definition at line 3806 of file float.c.

3807 {
3808  float4 arg1 = PG_GETARG_FLOAT4(0);
3809  float8 arg2 = PG_GETARG_FLOAT8(1);
3810 
3811  PG_RETURN_FLOAT8(float8_mi((float8) arg1, arg2));
3812 }
static float8 float8_mi(const float8 val1, const float8 val2)
Definition: float.h:181

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

◆ float48mul()

Datum float48mul ( PG_FUNCTION_ARGS  )

Definition at line 3815 of file float.c.

3816 {
3817  float4 arg1 = PG_GETARG_FLOAT4(0);
3818  float8 arg2 = PG_GETARG_FLOAT8(1);
3819 
3820  PG_RETURN_FLOAT8(float8_mul((float8) arg1, arg2));
3821 }
static float8 float8_mul(const float8 val1, const float8 val2)
Definition: float.h:207

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

◆ float48ne()

Datum float48ne ( PG_FUNCTION_ARGS  )

Definition at line 3893 of file float.c.

3894 {
3895  float4 arg1 = PG_GETARG_FLOAT4(0);
3896  float8 arg2 = PG_GETARG_FLOAT8(1);
3897 
3898  PG_RETURN_BOOL(float8_ne((float8) arg1, arg2));
3899 }
static bool float8_ne(const float8 val1, const float8 val2)
Definition: float.h:279

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

◆ float48pl()

Datum float48pl ( PG_FUNCTION_ARGS  )

Definition at line 3797 of file float.c.

3798 {
3799  float4 arg1 = PG_GETARG_FLOAT4(0);
3800  float8 arg2 = PG_GETARG_FLOAT8(1);
3801 
3802  PG_RETURN_FLOAT8(float8_pl((float8) arg1, arg2));
3803 }
static float8 float8_pl(const float8 val1, const float8 val2)
Definition: float.h:157

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

◆ float4_accum()

Datum float4_accum ( PG_FUNCTION_ARGS  )

Definition at line 3053 of file float.c.

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

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:285
static bool float4_gt(const float4 val1, const float4 val2)
Definition: float.h:309
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:221

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:261

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:321

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

164 {
165  char *num = PG_GETARG_CSTRING(0);
166  char *orig_num;
167  float val;
168  char *endptr;
169 
170  /*
171  * endptr points to the first character _after_ the sequence we recognized
172  * as a valid floating point number. orig_num points to the original input
173  * string.
174  */
175  orig_num = num;
176 
177  /* skip leading whitespace */
178  while (*num != '\0' && isspace((unsigned char) *num))
179  num++;
180 
181  /*
182  * Check for an empty-string input to begin with, to avoid the vagaries of
183  * strtod() on different platforms.
184  */
185  if (*num == '\0')
186  ereport(ERROR,
187  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
188  errmsg("invalid input syntax for type %s: \"%s\"",
189  "real", orig_num)));
190 
191  errno = 0;
192  val = strtof(num, &endptr);
193 
194  /* did we not see anything that looks like a double? */
195  if (endptr == num || errno != 0)
196  {
197  int save_errno = errno;
198 
199  /*
200  * C99 requires that strtof() accept NaN, [+-]Infinity, and [+-]Inf,
201  * but not all platforms support all of these (and some accept them
202  * but set ERANGE anyway...) Therefore, we check for these inputs
203  * ourselves if strtof() fails.
204  *
205  * Note: C99 also requires hexadecimal input as well as some extended
206  * forms of NaN, but we consider these forms unportable and don't try
207  * to support them. You can use 'em if your strtof() takes 'em.
208  */
209  if (pg_strncasecmp(num, "NaN", 3) == 0)
210  {
211  val = get_float4_nan();
212  endptr = num + 3;
213  }
214  else if (pg_strncasecmp(num, "Infinity", 8) == 0)
215  {
217  endptr = num + 8;
218  }
219  else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
220  {
222  endptr = num + 9;
223  }
224  else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
225  {
227  endptr = num + 9;
228  }
229  else if (pg_strncasecmp(num, "inf", 3) == 0)
230  {
232  endptr = num + 3;
233  }
234  else if (pg_strncasecmp(num, "+inf", 4) == 0)
235  {
237  endptr = num + 4;
238  }
239  else if (pg_strncasecmp(num, "-inf", 4) == 0)
240  {
242  endptr = num + 4;
243  }
244  else if (save_errno == ERANGE)
245  {
246  /*
247  * Some platforms return ERANGE for denormalized numbers (those
248  * that are not zero, but are too close to zero to have full
249  * precision). We'd prefer not to throw error for that, so try to
250  * detect whether it's a "real" out-of-range condition by checking
251  * to see if the result is zero or huge.
252  */
253  if (val == 0.0 ||
254 #if !defined(HUGE_VALF)
255  isinf(val)
256 #else
257  (val >= HUGE_VALF || val <= -HUGE_VALF)
258 #endif
259  )
260  ereport(ERROR,
261  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
262  errmsg("\"%s\" is out of range for type real",
263  orig_num)));
264  }
265  else
266  ereport(ERROR,
267  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
268  errmsg("invalid input syntax for type %s: \"%s\"",
269  "real", orig_num)));
270  }
271 
272  /* skip trailing whitespace */
273  while (*endptr != '\0' && isspace((unsigned char) *endptr))
274  endptr++;
275 
276  /* if there is any junk left at the end of the string, bail out */
277  if (*endptr != '\0')
278  ereport(ERROR,
279  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
280  errmsg("invalid input syntax for type %s: \"%s\"",
281  "real", orig_num)));
282 
284 }
static float4 get_float4_infinity(void)
Definition: float.h:73
static float4 get_float4_nan(void)
Definition: float.h:110
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
long val
Definition: informix.c:664
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69

References ereport, errcode(), errmsg(), ERROR, get_float4_infinity(), get_float4_nan(), PG_GETARG_CSTRING, PG_RETURN_FLOAT4, pg_strncasecmp(), and val.

Referenced by numeric_float4().

◆ 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:297

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:169

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:193

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:273

References float4_ne(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4out()

Datum float4out ( PG_FUNCTION_ARGS  )

Definition at line 291 of file float.c.

292 {
293  float4 num = PG_GETARG_FLOAT4(0);
294  char *ascii = (char *) palloc(32);
295  int ndig = FLT_DIG + extra_float_digits;
296 
297  if (extra_float_digits > 0)
298  {
301  }
302 
303  (void) pg_strfromd(ascii, 32, ndig, num);
305 }
int float_to_shortest_decimal_buf(float f, char *result)
Definition: f2s.c:780
int extra_float_digits
Definition: float.c:43
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
void * palloc(Size size)
Definition: mcxt.c:1199
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:145

References float4_pl(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4recv()

Datum float4recv ( PG_FUNCTION_ARGS  )

Definition at line 311 of file float.c.

312 {
314 
316 }
static char * buf
Definition: pg_test_fsync.c:67
float4 pq_getmsgfloat4(StringInfo msg)
Definition: pqformat.c:471
StringInfoData * StringInfo
Definition: stringinfo.h:44

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

◆ float4send()

Datum float4send ( PG_FUNCTION_ARGS  )

Definition at line 322 of file float.c.

323 {
324  float4 num = PG_GETARG_FLOAT4(0);
326 
328  pq_sendfloat4(&buf, num);
330 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
void pq_sendfloat4(StringInfo buf, float4 f)
Definition: pqformat.c:254
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348

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

3867 {
3868  float8 arg1 = PG_GETARG_FLOAT8(0);
3869  float4 arg2 = PG_GETARG_FLOAT4(1);
3870 
3871  PG_RETURN_FLOAT8(float8_div(arg1, (float8) arg2));
3872 }

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

◆ float84eq()

Datum float84eq ( PG_FUNCTION_ARGS  )

Definition at line 3941 of file float.c.

3942 {
3943  float8 arg1 = PG_GETARG_FLOAT8(0);
3944  float4 arg2 = PG_GETARG_FLOAT4(1);
3945 
3946  PG_RETURN_BOOL(float8_eq(arg1, (float8) arg2));
3947 }

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

◆ float84ge()

Datum float84ge ( PG_FUNCTION_ARGS  )

Definition at line 3986 of file float.c.

3987 {
3988  float8 arg1 = PG_GETARG_FLOAT8(0);
3989  float4 arg2 = PG_GETARG_FLOAT4(1);
3990 
3991  PG_RETURN_BOOL(float8_ge(arg1, (float8) arg2));
3992 }

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

◆ float84gt()

Datum float84gt ( PG_FUNCTION_ARGS  )

Definition at line 3977 of file float.c.

3978 {
3979  float8 arg1 = PG_GETARG_FLOAT8(0);
3980  float4 arg2 = PG_GETARG_FLOAT4(1);
3981 
3982  PG_RETURN_BOOL(float8_gt(arg1, (float8) arg2));
3983 }

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

◆ float84le()

Datum float84le ( PG_FUNCTION_ARGS  )

Definition at line 3968 of file float.c.

3969 {
3970  float8 arg1 = PG_GETARG_FLOAT8(0);
3971  float4 arg2 = PG_GETARG_FLOAT4(1);
3972 
3973  PG_RETURN_BOOL(float8_le(arg1, (float8) arg2));
3974 }

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

◆ float84lt()

Datum float84lt ( PG_FUNCTION_ARGS  )

Definition at line 3959 of file float.c.

3960 {
3961  float8 arg1 = PG_GETARG_FLOAT8(0);
3962  float4 arg2 = PG_GETARG_FLOAT4(1);
3963 
3964  PG_RETURN_BOOL(float8_lt(arg1, (float8) arg2));
3965 }

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

◆ float84mi()

Datum float84mi ( PG_FUNCTION_ARGS  )

Definition at line 3848 of file float.c.

3849 {
3850  float8 arg1 = PG_GETARG_FLOAT8(0);
3851  float4 arg2 = PG_GETARG_FLOAT4(1);
3852 
3853  PG_RETURN_FLOAT8(float8_mi(arg1, (float8) arg2));
3854 }

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

◆ float84mul()

Datum float84mul ( PG_FUNCTION_ARGS  )

Definition at line 3857 of file float.c.

3858 {
3859  float8 arg1 = PG_GETARG_FLOAT8(0);
3860  float4 arg2 = PG_GETARG_FLOAT4(1);
3861 
3862  PG_RETURN_FLOAT8(float8_mul(arg1, (float8) arg2));
3863 }

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

◆ float84ne()

Datum float84ne ( PG_FUNCTION_ARGS  )

Definition at line 3950 of file float.c.

3951 {
3952  float8 arg1 = PG_GETARG_FLOAT8(0);
3953  float4 arg2 = PG_GETARG_FLOAT4(1);
3954 
3955  PG_RETURN_BOOL(float8_ne(arg1, (float8) arg2));
3956 }

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

◆ float84pl()

Datum float84pl ( PG_FUNCTION_ARGS  )

Definition at line 3839 of file float.c.

3840 {
3841  float8 arg1 = PG_GETARG_FLOAT8(0);
3842  float4 arg2 = PG_GETARG_FLOAT4(1);
3843 
3844  PG_RETURN_FLOAT8(float8_pl(arg1, (float8) arg2));
3845 }

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

◆ float8_accum()

Datum float8_accum ( PG_FUNCTION_ARGS  )

Definition at line 2970 of file float.c.

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

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

3139 {
3140  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3141  float8 *transvalues;
3142  float8 N,
3143  Sx;
3144 
3145  transvalues = check_float8_array(transarray, "float8_avg", 3);
3146  N = transvalues[0];
3147  Sx = transvalues[1];
3148  /* ignore Sxx */
3149 
3150  /* SQL defines AVG of no values to be NULL */
3151  if (N == 0.0)
3152  PG_RETURN_NULL();
3153 
3154  PG_RETURN_FLOAT8(Sx / N);
3155 }
#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 2876 of file float.c.

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

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

3665 {
3666  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3667  float8 *transvalues;
3668  float8 N,
3669  Sxx,
3670  Syy,
3671  Sxy;
3672 
3673  transvalues = check_float8_array(transarray, "float8_corr", 6);
3674  N = transvalues[0];
3675  Sxx = transvalues[2];
3676  Syy = transvalues[4];
3677  Sxy = transvalues[5];
3678 
3679  /* if N is 0 we should return NULL */
3680  if (N < 1.0)
3681  PG_RETURN_NULL();
3682 
3683  /* Note that Sxx and Syy are guaranteed to be non-negative */
3684 
3685  /* per spec, return NULL for horizontal and vertical lines */
3686  if (Sxx == 0 || Syy == 0)
3687  PG_RETURN_NULL();
3688 
3689  PG_RETURN_FLOAT8(Sxy / sqrt(Sxx * Syy));
3690 }

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

3627 {
3628  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3629  float8 *transvalues;
3630  float8 N,
3631  Sxy;
3632 
3633  transvalues = check_float8_array(transarray, "float8_covar_pop", 6);
3634  N = transvalues[0];
3635  Sxy = transvalues[5];
3636 
3637  /* if N is 0 we should return NULL */
3638  if (N < 1.0)
3639  PG_RETURN_NULL();
3640 
3641  PG_RETURN_FLOAT8(Sxy / N);
3642 }

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

3646 {
3647  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3648  float8 *transvalues;
3649  float8 N,
3650  Sxy;
3651 
3652  transvalues = check_float8_array(transarray, "float8_covar_samp", 6);
3653  N = transvalues[0];
3654  Sxy = transvalues[5];
3655 
3656  /* if N is <= 1 we should return NULL */
3657  if (N < 2.0)
3658  PG_RETURN_NULL();
3659 
3660  PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3661 }

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

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

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

3589 {
3590  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3591  float8 *transvalues;
3592  float8 N,
3593  Sx;
3594 
3595  transvalues = check_float8_array(transarray, "float8_regr_avgx", 6);
3596  N = transvalues[0];
3597  Sx = transvalues[1];
3598 
3599  /* if N is 0 we should return NULL */
3600  if (N < 1.0)
3601  PG_RETURN_NULL();
3602 
3603  PG_RETURN_FLOAT8(Sx / N);
3604 }

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

3608 {
3609  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3610  float8 *transvalues;
3611  float8 N,
3612  Sy;
3613 
3614  transvalues = check_float8_array(transarray, "float8_regr_avgy", 6);
3615  N = transvalues[0];
3616  Sy = transvalues[3];
3617 
3618  /* if N is 0 we should return NULL */
3619  if (N < 1.0)
3620  PG_RETURN_NULL();
3621 
3622  PG_RETURN_FLOAT8(Sy / N);
3623 }

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

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

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

3754 {
3755  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3756  float8 *transvalues;
3757  float8 N,
3758  Sx,
3759  Sxx,
3760  Sy,
3761  Sxy;
3762 
3763  transvalues = check_float8_array(transarray, "float8_regr_intercept", 6);
3764  N = transvalues[0];
3765  Sx = transvalues[1];
3766  Sxx = transvalues[2];
3767  Sy = transvalues[3];
3768  Sxy = transvalues[5];
3769 
3770  /* if N is 0 we should return NULL */
3771  if (N < 1.0)
3772  PG_RETURN_NULL();
3773 
3774  /* Note that Sxx is guaranteed to be non-negative */
3775 
3776  /* per spec, return NULL for a vertical line */
3777  if (Sxx == 0)
3778  PG_RETURN_NULL();
3779 
3780  PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
3781 }

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

3694 {
3695  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3696  float8 *transvalues;
3697  float8 N,
3698  Sxx,
3699  Syy,
3700  Sxy;
3701 
3702  transvalues = check_float8_array(transarray, "float8_regr_r2", 6);
3703  N = transvalues[0];
3704  Sxx = transvalues[2];
3705  Syy = transvalues[4];
3706  Sxy = transvalues[5];
3707 
3708  /* if N is 0 we should return NULL */
3709  if (N < 1.0)
3710  PG_RETURN_NULL();
3711 
3712  /* Note that Sxx and Syy are guaranteed to be non-negative */
3713 
3714  /* per spec, return NULL for a vertical line */
3715  if (Sxx == 0)
3716  PG_RETURN_NULL();
3717 
3718  /* per spec, return 1.0 for a horizontal line */
3719  if (Syy == 0)
3720  PG_RETURN_FLOAT8(1.0);
3721 
3722  PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3723 }

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

3727 {
3728  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3729  float8 *transvalues;
3730  float8 N,
3731  Sxx,
3732  Sxy;
3733 
3734  transvalues = check_float8_array(transarray, "float8_regr_slope", 6);
3735  N = transvalues[0];
3736  Sxx = transvalues[2];
3737  Sxy = transvalues[5];
3738 
3739  /* if N is 0 we should return NULL */
3740  if (N < 1.0)
3741  PG_RETURN_NULL();
3742 
3743  /* Note that Sxx is guaranteed to be non-negative */
3744 
3745  /* per spec, return NULL for a vertical line */
3746  if (Sxx == 0)
3747  PG_RETURN_NULL();
3748 
3749  PG_RETURN_FLOAT8(Sxy / Sxx);
3750 }

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

3526 {
3527  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3528  float8 *transvalues;
3529  float8 N,
3530  Sxx;
3531 
3532  transvalues = check_float8_array(transarray, "float8_regr_sxx", 6);
3533  N = transvalues[0];
3534  Sxx = transvalues[2];
3535 
3536  /* if N is 0 we should return NULL */
3537  if (N < 1.0)
3538  PG_RETURN_NULL();
3539 
3540  /* Note that Sxx is guaranteed to be non-negative */
3541 
3542  PG_RETURN_FLOAT8(Sxx);
3543 }

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

3568 {
3569  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3570  float8 *transvalues;
3571  float8 N,
3572  Sxy;
3573 
3574  transvalues = check_float8_array(transarray, "float8_regr_sxy", 6);
3575  N = transvalues[0];
3576  Sxy = transvalues[5];
3577 
3578  /* if N is 0 we should return NULL */
3579  if (N < 1.0)
3580  PG_RETURN_NULL();
3581 
3582  /* A negative result is valid here */
3583 
3584  PG_RETURN_FLOAT8(Sxy);
3585 }

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

3547 {
3548  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3549  float8 *transvalues;
3550  float8 N,
3551  Syy;
3552 
3553  transvalues = check_float8_array(transarray, "float8_regr_syy", 6);
3554  N = transvalues[0];
3555  Syy = transvalues[4];
3556 
3557  /* if N is 0 we should return NULL */
3558  if (N < 1.0)
3559  PG_RETURN_NULL();
3560 
3561  /* Note that Syy is guaranteed to be non-negative */
3562 
3563  PG_RETURN_FLOAT8(Syy);
3564 }

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

3203 {
3204  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3205  float8 *transvalues;
3206  float8 N,
3207  Sxx;
3208 
3209  transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
3210  N = transvalues[0];
3211  /* ignore Sx */
3212  Sxx = transvalues[2];
3213 
3214  /* Population stddev is undefined when N is 0, so return NULL */
3215  if (N == 0.0)
3216  PG_RETURN_NULL();
3217 
3218  /* Note that Sxx is guaranteed to be non-negative */
3219 
3220  PG_RETURN_FLOAT8(sqrt(Sxx / N));
3221 }

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

3225 {
3226  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3227  float8 *transvalues;
3228  float8 N,
3229  Sxx;
3230 
3231  transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
3232  N = transvalues[0];
3233  /* ignore Sx */
3234  Sxx = transvalues[2];
3235 
3236  /* Sample stddev is undefined when N is 0 or 1, so return NULL */
3237  if (N <= 1.0)
3238  PG_RETURN_NULL();
3239 
3240  /* Note that Sxx is guaranteed to be non-negative */
3241 
3242  PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0)));
3243 }

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

3159 {
3160  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3161  float8 *transvalues;
3162  float8 N,
3163  Sxx;
3164 
3165  transvalues = check_float8_array(transarray, "float8_var_pop", 3);
3166  N = transvalues[0];
3167  /* ignore Sx */
3168  Sxx = transvalues[2];
3169 
3170  /* Population variance is undefined when N is 0, so return NULL */
3171  if (N == 0.0)
3172  PG_RETURN_NULL();
3173 
3174  /* Note that Sxx is guaranteed to be non-negative */
3175 
3176  PG_RETURN_FLOAT8(Sxx / N);
3177 }

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

3181 {
3182  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3183  float8 *transvalues;
3184  float8 N,
3185  Sxx;
3186 
3187  transvalues = check_float8_array(transarray, "float8_var_samp", 3);
3188  N = transvalues[0];
3189  /* ignore Sx */
3190  Sxx = transvalues[2];
3191 
3192  /* Sample variance is undefined when N is 0 or 1, so return NULL */
3193  if (N <= 1.0)
3194  PG_RETURN_NULL();
3195 
3196  /* Note that Sxx is guaranteed to be non-negative */
3197 
3198  PG_RETURN_FLOAT8(Sxx / (N - 1.0));
3199 }

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

337 {
338  char *num = PG_GETARG_CSTRING(0);
339 
340  PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num));
341 }
double float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string)
Definition: float.c:510

References float8in_internal(), PG_GETARG_CSTRING, and PG_RETURN_FLOAT8.

Referenced by numeric_float8().

◆ float8in_internal()

double float8in_internal ( char *  num,
char **  endptr_p,
const char *  type_name,
const char *  orig_string 
)

Definition at line 510 of file float.c.

512 {
513  return float8in_internal_opt_error(num, endptr_p, type_name,
514  orig_string, NULL);
515 }
double float8in_internal_opt_error(char *num, char **endptr_p, const char *type_name, const char *orig_string, bool *have_error)
Definition: float.c:376

References float8in_internal_opt_error().

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

◆ float8in_internal_opt_error()

double float8in_internal_opt_error ( char *  num,
char **  endptr_p,
const char *  type_name,
const char *  orig_string,
bool have_error 
)

Definition at line 376 of file float.c.

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

References ereport, errcode(), errmsg(), ERROR, get_float8_infinity(), get_float8_nan(), pg_strncasecmp(), pstrdup(), RETURN_ERROR, and val.

Referenced by executeItemOptUnwrapTarget(), and float8in_internal().

◆ 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:490

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:278

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

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

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

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

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:1039

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:1041

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:63
float8 degree_c_thirty
Definition: float.c:61
float8 degree_c_forty_five
Definition: float.c:62
static float8 sin_30
Definition: float.c:47
float8 degree_c_one
Definition: float.c:65
float8 degree_c_one_half
Definition: float.c:64

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

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

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.

◆ setseed()

Datum setseed ( PG_FUNCTION_ARGS  )

Definition at line 2785 of file float.c.

2786 {
2787  float8 seed = PG_GETARG_FLOAT8(0);
2788 
2789  if (seed < -1 || seed > 1 || isnan(seed))
2790  ereport(ERROR,
2791  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2792  errmsg("setseed parameter %g is out of allowed range [-1,1]",
2793  seed)));
2794 
2795  pg_prng_fseed(&drandom_seed, seed);
2796  drandom_seed_set = true;
2797 
2798  PG_RETURN_VOID();
2799 }
void pg_prng_fseed(pg_prng_state *state, double fseed)
Definition: pg_prng.c:96

References drandom_seed, drandom_seed_set, ereport, errcode(), errmsg(), ERROR, PG_GETARG_FLOAT8, pg_prng_fseed(), and PG_RETURN_VOID.

Referenced by assign_random_seed().

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

4010 {
4011  float8 operand = PG_GETARG_FLOAT8(0);
4012  float8 bound1 = PG_GETARG_FLOAT8(1);
4013  float8 bound2 = PG_GETARG_FLOAT8(2);
4014  int32 count = PG_GETARG_INT32(3);
4015  int32 result;
4016 
4017  if (count <= 0.0)
4018  ereport(ERROR,
4019  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4020  errmsg("count must be greater than zero")));
4021 
4022  if (isnan(operand) || isnan(bound1) || isnan(bound2))
4023  ereport(ERROR,
4024  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4025  errmsg("operand, lower bound, and upper bound cannot be NaN")));
4026 
4027  /* Note that we allow "operand" to be infinite */
4028  if (isinf(bound1) || isinf(bound2))
4029  ereport(ERROR,
4030  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4031  errmsg("lower and upper bounds must be finite")));
4032 
4033  if (bound1 < bound2)
4034  {
4035  if (operand < bound1)
4036  result = 0;
4037  else if (operand >= bound2)
4038  {
4039  if (pg_add_s32_overflow(count, 1, &result))
4040  ereport(ERROR,
4041  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4042  errmsg("integer out of range")));
4043  }
4044  else
4045  result = ((float8) count * (operand - bound1) / (bound2 - bound1)) + 1;
4046  }
4047  else if (bound1 > bound2)
4048  {
4049  if (operand > bound1)
4050  result = 0;
4051  else if (operand <= bound2)
4052  {
4053  if (pg_add_s32_overflow(count, 1, &result))
4054  ereport(ERROR,
4055  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4056  errmsg("integer out of range")));
4057  }
4058  else
4059  result = ((float8) count * (bound1 - operand) / (bound1 - bound2)) + 1;
4060  }
4061  else
4062  {
4063  ereport(ERROR,
4064  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4065  errmsg("lower bound cannot equal upper bound")));
4066  result = 0; /* keep the compiler quiet */
4067  }
4068 
4069  PG_RETURN_INT32(result);
4070 }
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 50 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 49 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 51 of file float.c.

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

◆ cot_45

float8 cot_45 = 0
static

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

Referenced by init_degree_constants().

◆ degree_c_one

float8 degree_c_one = 1.0

Definition at line 65 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_one_half

float8 degree_c_one_half = 0.5

Definition at line 64 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_sixty

float8 degree_c_sixty = 60.0

Definition at line 63 of file float.c.

Referenced by init_degree_constants().

◆ degree_c_thirty

float8 degree_c_thirty = 30.0

Definition at line 61 of file float.c.

Referenced by init_degree_constants().

◆ degree_consts_set

bool degree_consts_set = false
static

Definition at line 46 of file float.c.

Referenced by init_degree_constants().

◆ drandom_seed

pg_prng_state drandom_seed
static

Definition at line 69 of file float.c.

Referenced by drandom(), and setseed().

◆ drandom_seed_set

bool drandom_seed_set = false
static

Definition at line 68 of file float.c.

Referenced by drandom(), and setseed().

◆ extra_float_digits

int extra_float_digits = 1

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

Referenced by cosd_0_to_60(), and init_degree_constants().

◆ sin_30

float8 sin_30 = 0
static

Definition at line 47 of file float.c.

Referenced by init_degree_constants(), and sind_0_to_30().

◆ tan_45

float8 tan_45 = 0
static

Definition at line 52 of file float.c.

Referenced by dtand(), and init_degree_constants().