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 INIT_DEGREE_CONSTANTS()
 

Functions

static double sind_q1 (double x)
 
static double cosd_q1 (double x)
 
static void init_degree_constants (void)
 
pg_noinline void float_overflow_error (void)
 
pg_noinline void float_underflow_error (void)
 
pg_noinline void float_zero_divide_error (void)
 
int is_infinite (double val)
 
Datum float4in (PG_FUNCTION_ARGS)
 
float4 float4in_internal (char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
 
Datum float4out (PG_FUNCTION_ARGS)
 
Datum float4recv (PG_FUNCTION_ARGS)
 
Datum float4send (PG_FUNCTION_ARGS)
 
Datum float8in (PG_FUNCTION_ARGS)
 
float8 float8in_internal (char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
 
Datum float8out (PG_FUNCTION_ARGS)
 
char * float8out_internal (double num)
 
Datum float8recv (PG_FUNCTION_ARGS)
 
Datum float8send (PG_FUNCTION_ARGS)
 
Datum float4abs (PG_FUNCTION_ARGS)
 
Datum float4um (PG_FUNCTION_ARGS)
 
Datum float4up (PG_FUNCTION_ARGS)
 
Datum float4larger (PG_FUNCTION_ARGS)
 
Datum float4smaller (PG_FUNCTION_ARGS)
 
Datum float8abs (PG_FUNCTION_ARGS)
 
Datum float8um (PG_FUNCTION_ARGS)
 
Datum float8up (PG_FUNCTION_ARGS)
 
Datum float8larger (PG_FUNCTION_ARGS)
 
Datum float8smaller (PG_FUNCTION_ARGS)
 
Datum float4pl (PG_FUNCTION_ARGS)
 
Datum float4mi (PG_FUNCTION_ARGS)
 
Datum float4mul (PG_FUNCTION_ARGS)
 
Datum float4div (PG_FUNCTION_ARGS)
 
Datum float8pl (PG_FUNCTION_ARGS)
 
Datum float8mi (PG_FUNCTION_ARGS)
 
Datum float8mul (PG_FUNCTION_ARGS)
 
Datum float8div (PG_FUNCTION_ARGS)
 
int float4_cmp_internal (float4 a, float4 b)
 
Datum float4eq (PG_FUNCTION_ARGS)
 
Datum float4ne (PG_FUNCTION_ARGS)
 
Datum float4lt (PG_FUNCTION_ARGS)
 
Datum float4le (PG_FUNCTION_ARGS)
 
Datum float4gt (PG_FUNCTION_ARGS)
 
Datum float4ge (PG_FUNCTION_ARGS)
 
Datum btfloat4cmp (PG_FUNCTION_ARGS)
 
static int btfloat4fastcmp (Datum x, Datum y, SortSupport ssup)
 
Datum btfloat4sortsupport (PG_FUNCTION_ARGS)
 
int float8_cmp_internal (float8 a, float8 b)
 
Datum float8eq (PG_FUNCTION_ARGS)
 
Datum float8ne (PG_FUNCTION_ARGS)
 
Datum float8lt (PG_FUNCTION_ARGS)
 
Datum float8le (PG_FUNCTION_ARGS)
 
Datum float8gt (PG_FUNCTION_ARGS)
 
Datum float8ge (PG_FUNCTION_ARGS)
 
Datum btfloat8cmp (PG_FUNCTION_ARGS)
 
static int btfloat8fastcmp (Datum x, Datum y, SortSupport ssup)
 
Datum btfloat8sortsupport (PG_FUNCTION_ARGS)
 
Datum btfloat48cmp (PG_FUNCTION_ARGS)
 
Datum btfloat84cmp (PG_FUNCTION_ARGS)
 
Datum in_range_float8_float8 (PG_FUNCTION_ARGS)
 
Datum in_range_float4_float8 (PG_FUNCTION_ARGS)
 
Datum ftod (PG_FUNCTION_ARGS)
 
Datum dtof (PG_FUNCTION_ARGS)
 
Datum dtoi4 (PG_FUNCTION_ARGS)
 
Datum dtoi2 (PG_FUNCTION_ARGS)
 
Datum i4tod (PG_FUNCTION_ARGS)
 
Datum i2tod (PG_FUNCTION_ARGS)
 
Datum ftoi4 (PG_FUNCTION_ARGS)
 
Datum ftoi2 (PG_FUNCTION_ARGS)
 
Datum i4tof (PG_FUNCTION_ARGS)
 
Datum i2tof (PG_FUNCTION_ARGS)
 
Datum dround (PG_FUNCTION_ARGS)
 
Datum dceil (PG_FUNCTION_ARGS)
 
Datum dfloor (PG_FUNCTION_ARGS)
 
Datum dsign (PG_FUNCTION_ARGS)
 
Datum dtrunc (PG_FUNCTION_ARGS)
 
Datum dsqrt (PG_FUNCTION_ARGS)
 
Datum dcbrt (PG_FUNCTION_ARGS)
 
Datum dpow (PG_FUNCTION_ARGS)
 
Datum dexp (PG_FUNCTION_ARGS)
 
Datum dlog1 (PG_FUNCTION_ARGS)
 
Datum dlog10 (PG_FUNCTION_ARGS)
 
Datum dacos (PG_FUNCTION_ARGS)
 
Datum dasin (PG_FUNCTION_ARGS)
 
Datum datan (PG_FUNCTION_ARGS)
 
Datum datan2 (PG_FUNCTION_ARGS)
 
Datum dcos (PG_FUNCTION_ARGS)
 
Datum dcot (PG_FUNCTION_ARGS)
 
Datum dsin (PG_FUNCTION_ARGS)
 
Datum dtan (PG_FUNCTION_ARGS)
 
static double asind_q1 (double x)
 
static double acosd_q1 (double x)
 
Datum dacosd (PG_FUNCTION_ARGS)
 
Datum dasind (PG_FUNCTION_ARGS)
 
Datum datand (PG_FUNCTION_ARGS)
 
Datum datan2d (PG_FUNCTION_ARGS)
 
static double sind_0_to_30 (double x)
 
static double cosd_0_to_60 (double x)
 
Datum dcosd (PG_FUNCTION_ARGS)
 
Datum dcotd (PG_FUNCTION_ARGS)
 
Datum dsind (PG_FUNCTION_ARGS)
 
Datum dtand (PG_FUNCTION_ARGS)
 
Datum degrees (PG_FUNCTION_ARGS)
 
Datum dpi (PG_FUNCTION_ARGS)
 
Datum radians (PG_FUNCTION_ARGS)
 
Datum dsinh (PG_FUNCTION_ARGS)
 
Datum dcosh (PG_FUNCTION_ARGS)
 
Datum dtanh (PG_FUNCTION_ARGS)
 
Datum dasinh (PG_FUNCTION_ARGS)
 
Datum dacosh (PG_FUNCTION_ARGS)
 
Datum datanh (PG_FUNCTION_ARGS)
 
Datum derf (PG_FUNCTION_ARGS)
 
Datum derfc (PG_FUNCTION_ARGS)
 
static void initialize_drandom_seed (void)
 
Datum drandom (PG_FUNCTION_ARGS)
 
Datum drandom_normal (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 2031 of file float.c.

Function Documentation

◆ acosd_q1()

static double acosd_q1 ( double  x)
static

Definition at line 2081 of file float.c.

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

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

References acos_0_5, asin_0_5, and x.

Referenced by dacosd(), and dasind().

◆ btfloat48cmp()

Datum btfloat48cmp ( PG_FUNCTION_ARGS  )

Definition at line 1001 of file float.c.

1002 {
1003  float4 arg1 = PG_GETARG_FLOAT4(0);
1004  float8 arg2 = PG_GETARG_FLOAT8(1);
1005 
1006  /* widen float4 to float8 and then compare */
1007  PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
1008 }
float float4
Definition: c.h:613
int float8_cmp_internal(float8 a, float8 b)
Definition: float.c:910
#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 880 of file float.c.

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

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

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

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

Referenced by btfloat4sortsupport().

◆ btfloat4sortsupport()

Datum btfloat4sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 898 of file float.c.

899 {
901 
902  ssup->comparator = btfloat4fastcmp;
903  PG_RETURN_VOID();
904 }
static int btfloat4fastcmp(Datum x, Datum y, SortSupport ssup)
Definition: float.c:889
#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 1011 of file float.c.

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

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

◆ btfloat8cmp()

Datum btfloat8cmp ( PG_FUNCTION_ARGS  )

Definition at line 974 of file float.c.

975 {
976  float8 arg1 = PG_GETARG_FLOAT8(0);
977  float8 arg2 = PG_GETARG_FLOAT8(1);
978 
980 }

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

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

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

Referenced by btfloat8sortsupport().

◆ btfloat8sortsupport()

Datum btfloat8sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 992 of file float.c.

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

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

◆ check_float8_array()

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

Definition at line 2928 of file float.c.

2929 {
2930  /*
2931  * We expect the input to be an N-element float array; verify that. We
2932  * don't need to use deconstruct_array() since the array data is just
2933  * going to look like a C array of N float8 values.
2934  */
2935  if (ARR_NDIM(transarray) != 1 ||
2936  ARR_DIMS(transarray)[0] != n ||
2937  ARR_HASNULL(transarray) ||
2938  ARR_ELEMTYPE(transarray) != FLOAT8OID)
2939  elog(ERROR, "%s: expected %d-element float8 array", caller, n);
2940  return (float8 *) ARR_DATA_PTR(transarray);
2941 }
#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:39

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

2267 {
2268  volatile float8 one_minus_cos_x = 1.0 - cos(x * RADIANS_PER_DEGREE);
2269 
2270  return 1.0 - (one_minus_cos_x / one_minus_cos_60) / 2.0;
2271 }
static float8 one_minus_cos_60
Definition: float.c: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 2299 of file float.c.

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

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

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

◆ dacos()

Datum dacos ( PG_FUNCTION_ARGS  )

Definition at line 1755 of file float.c.

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

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

◆ dacosd()

Datum dacosd ( PG_FUNCTION_ARGS  )

Definition at line 2108 of file float.c.

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

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

◆ dacosh()

Datum dacosh ( PG_FUNCTION_ARGS  )

Definition at line 2689 of file float.c.

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

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

◆ dasin()

Datum dasin ( PG_FUNCTION_ARGS  )

Definition at line 1786 of file float.c.

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

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

◆ dasind()

Datum dasind ( PG_FUNCTION_ARGS  )

Definition at line 2145 of file float.c.

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

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

◆ dasinh()

Datum dasinh ( PG_FUNCTION_ARGS  )

Definition at line 2672 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ datan()

Datum datan ( PG_FUNCTION_ARGS  )

Definition at line 1817 of file float.c.

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

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

◆ datan2()

Datum datan2 ( PG_FUNCTION_ARGS  )

Definition at line 1843 of file float.c.

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

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

◆ datan2d()

Datum datan2d ( PG_FUNCTION_ARGS  )

Definition at line 2214 of file float.c.

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

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

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

◆ datanh()

Datum datanh ( PG_FUNCTION_ARGS  )

Definition at line 2714 of file float.c.

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

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

◆ dcbrt()

Datum dcbrt ( PG_FUNCTION_ARGS  )

Definition at line 1470 of file float.c.

1471 {
1472  float8 arg1 = PG_GETARG_FLOAT8(0);
1473  float8 result;
1474 
1475  result = cbrt(arg1);
1476  if (unlikely(isinf(result)) && !isinf(arg1))
1478  if (unlikely(result == 0.0) && arg1 != 0.0)
1480 
1481  PG_RETURN_FLOAT8(result);
1482 }
pg_noinline void float_underflow_error(void)
Definition: float.c: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 1380 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dcos()

Datum dcos ( PG_FUNCTION_ARGS  )

Definition at line 1869 of file float.c.

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

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

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

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

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

◆ dcot()

Datum dcot ( PG_FUNCTION_ARGS  )

Definition at line 1910 of file float.c.

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

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

◆ dcotd()

Datum dcotd ( PG_FUNCTION_ARGS  )

Definition at line 2373 of file float.c.

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

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

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

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

Referenced by degtorad().

◆ derf()

Datum derf ( PG_FUNCTION_ARGS  )

Definition at line 2752 of file float.c.

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

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

◆ derfc()

Datum derfc ( PG_FUNCTION_ARGS  )

Definition at line 2772 of file float.c.

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

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

◆ dexp()

Datum dexp ( PG_FUNCTION_ARGS  )

Definition at line 1644 of file float.c.

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

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

◆ dfloor()

Datum dfloor ( PG_FUNCTION_ARGS  )

Definition at line 1392 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dlog1()

Datum dlog1 ( PG_FUNCTION_ARGS  )

Definition at line 1690 of file float.c.

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

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

◆ dlog10()

Datum dlog10 ( PG_FUNCTION_ARGS  )

Definition at line 1722 of file float.c.

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

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

◆ dpi()

Definition at line 2573 of file float.c.

2574 {
2576 }
#define M_PI
Definition: earthdistance.c:11

References M_PI, and PG_RETURN_FLOAT8.

◆ dpow()

Datum dpow ( PG_FUNCTION_ARGS  )

Definition at line 1489 of file float.c.

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

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

2824 {
2825  float8 result;
2826 
2828 
2829  /* pg_prng_double produces desired result range [0.0 - 1.0) */
2830  result = pg_prng_double(&drandom_seed);
2831 
2832  PG_RETURN_FLOAT8(result);
2833 }
static void initialize_drandom_seed(void)
Definition: float.c:2796
static pg_prng_state drandom_seed
Definition: float.c:69
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:232

References drandom_seed, initialize_drandom_seed(), pg_prng_double(), and PG_RETURN_FLOAT8.

◆ drandom_normal()

Datum drandom_normal ( PG_FUNCTION_ARGS  )

Definition at line 2839 of file float.c.

2840 {
2841  float8 mean = PG_GETARG_FLOAT8(0);
2842  float8 stddev = PG_GETARG_FLOAT8(1);
2843  float8 result,
2844  z;
2845 
2847 
2848  /* Get random value from standard normal(mean = 0.0, stddev = 1.0) */
2850  /* Transform the normal standard variable (z) */
2851  /* using the target normal distribution parameters */
2852  result = (stddev * z) + mean;
2853 
2854  PG_RETURN_FLOAT8(result);
2855 }
double pg_prng_double_normal(pg_prng_state *state)
Definition: pg_prng.c:254

References drandom_seed, initialize_drandom_seed(), PG_GETARG_FLOAT8, pg_prng_double_normal(), and PG_RETURN_FLOAT8.

◆ dround()

Datum dround ( PG_FUNCTION_ARGS  )

Definition at line 1368 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsign()

Datum dsign ( PG_FUNCTION_ARGS  )

Definition at line 1405 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsin()

Datum dsin ( PG_FUNCTION_ARGS  )

Definition at line 1938 of file float.c.

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

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

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

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

◆ dsinh()

Datum dsinh ( PG_FUNCTION_ARGS  )

Definition at line 2598 of file float.c.

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

References get_float8_infinity(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsqrt()

Datum dsqrt ( PG_FUNCTION_ARGS  )

Definition at line 1446 of file float.c.

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

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

◆ dtan()

Datum dtan ( PG_FUNCTION_ARGS  )

Definition at line 1965 of file float.c.

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

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

◆ dtand()

Datum dtand ( PG_FUNCTION_ARGS  )

Definition at line 2495 of file float.c.

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

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

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

◆ dtof()

Datum dtof ( PG_FUNCTION_ARGS  )

Definition at line 1195 of file float.c.

1196 {
1197  float8 num = PG_GETARG_FLOAT8(0);
1198  float4 result;
1199 
1200  result = (float4) num;
1201  if (unlikely(isinf(result)) && !isinf(num))
1203  if (unlikely(result == 0.0f) && num != 0.0)
1205 
1206  PG_RETURN_FLOAT4(result);
1207 }
#define PG_RETURN_FLOAT4(x)
Definition: fmgr.h: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 1239 of file float.c.

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

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

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

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float48div()

Datum float48div ( PG_FUNCTION_ARGS  )

Definition at line 3900 of file float.c.

3901 {
3902  float4 arg1 = PG_GETARG_FLOAT4(0);
3903  float8 arg2 = PG_GETARG_FLOAT8(1);
3904 
3905  PG_RETURN_FLOAT8(float8_div((float8) arg1, arg2));
3906 }

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

◆ float48eq()

Datum float48eq ( PG_FUNCTION_ARGS  )

Definition at line 3960 of file float.c.

3961 {
3962  float4 arg1 = PG_GETARG_FLOAT4(0);
3963  float8 arg2 = PG_GETARG_FLOAT8(1);
3964 
3965  PG_RETURN_BOOL(float8_eq((float8) arg1, arg2));
3966 }
static bool float8_eq(const float8 val1, const float8 val2)
Definition: float.h:268
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

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

◆ float48ge()

Datum float48ge ( PG_FUNCTION_ARGS  )

Definition at line 4005 of file float.c.

4006 {
4007  float4 arg1 = PG_GETARG_FLOAT4(0);
4008  float8 arg2 = PG_GETARG_FLOAT8(1);
4009 
4010  PG_RETURN_BOOL(float8_ge((float8) arg1, arg2));
4011 }
static bool float8_ge(const float8 val1, const float8 val2)
Definition: float.h:328

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

◆ float48gt()

Datum float48gt ( PG_FUNCTION_ARGS  )

Definition at line 3996 of file float.c.

3997 {
3998  float4 arg1 = PG_GETARG_FLOAT4(0);
3999  float8 arg2 = PG_GETARG_FLOAT8(1);
4000 
4001  PG_RETURN_BOOL(float8_gt((float8) arg1, arg2));
4002 }
static bool float8_gt(const float8 val1, const float8 val2)
Definition: float.h:316

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

◆ float48le()

Datum float48le ( PG_FUNCTION_ARGS  )

Definition at line 3987 of file float.c.

3988 {
3989  float4 arg1 = PG_GETARG_FLOAT4(0);
3990  float8 arg2 = PG_GETARG_FLOAT8(1);
3991 
3992  PG_RETURN_BOOL(float8_le((float8) arg1, arg2));
3993 }
static bool float8_le(const float8 val1, const float8 val2)
Definition: float.h:304

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

◆ float48lt()

Datum float48lt ( PG_FUNCTION_ARGS  )

Definition at line 3978 of file float.c.

3979 {
3980  float4 arg1 = PG_GETARG_FLOAT4(0);
3981  float8 arg2 = PG_GETARG_FLOAT8(1);
3982 
3983  PG_RETURN_BOOL(float8_lt((float8) arg1, arg2));
3984 }
static bool float8_lt(const float8 val1, const float8 val2)
Definition: float.h:292

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

◆ float48mi()

Datum float48mi ( PG_FUNCTION_ARGS  )

Definition at line 3882 of file float.c.

3883 {
3884  float4 arg1 = PG_GETARG_FLOAT4(0);
3885  float8 arg2 = PG_GETARG_FLOAT8(1);
3886 
3887  PG_RETURN_FLOAT8(float8_mi((float8) arg1, arg2));
3888 }
static float8 float8_mi(const float8 val1, const float8 val2)
Definition: float.h:182

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

◆ float48mul()

Datum float48mul ( PG_FUNCTION_ARGS  )

Definition at line 3891 of file float.c.

3892 {
3893  float4 arg1 = PG_GETARG_FLOAT4(0);
3894  float8 arg2 = PG_GETARG_FLOAT8(1);
3895 
3896  PG_RETURN_FLOAT8(float8_mul((float8) arg1, arg2));
3897 }
static float8 float8_mul(const float8 val1, const float8 val2)
Definition: float.h:208

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

◆ float48ne()

Datum float48ne ( PG_FUNCTION_ARGS  )

Definition at line 3969 of file float.c.

3970 {
3971  float4 arg1 = PG_GETARG_FLOAT4(0);
3972  float8 arg2 = PG_GETARG_FLOAT8(1);
3973 
3974  PG_RETURN_BOOL(float8_ne((float8) arg1, arg2));
3975 }
static bool float8_ne(const float8 val1, const float8 val2)
Definition: float.h:280

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

◆ float48pl()

Datum float48pl ( PG_FUNCTION_ARGS  )

Definition at line 3873 of file float.c.

3874 {
3875  float4 arg1 = PG_GETARG_FLOAT4(0);
3876  float8 arg2 = PG_GETARG_FLOAT8(1);
3877 
3878  PG_RETURN_FLOAT8(float8_pl((float8) arg1, arg2));
3879 }
static float8 float8_pl(const float8 val1, const float8 val2)
Definition: float.h:158

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

◆ float4_accum()

Datum float4_accum ( PG_FUNCTION_ARGS  )

Definition at line 3129 of file float.c.

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

References AggCheckCallContext(), check_float8_array(), construct_array(), Float8GetDatumFast, FLOAT8PASSBYVAL, float_overflow_error(), get_float8_nan(), newval, PG_GETARG_ARRAYTYPE_P, PG_GETARG_FLOAT4, and PG_RETURN_ARRAYTYPE_P.

◆ float4_cmp_internal()

int float4_cmp_internal ( float4  a,
float4  b 
)

Definition at line 816 of file float.c.

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

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

Referenced by btfloat4cmp(), and btfloat4fastcmp().

◆ float4abs()

Datum float4abs ( PG_FUNCTION_ARGS  )

Definition at line 591 of file float.c.

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

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4div()

Datum float4div ( PG_FUNCTION_ARGS  )

Definition at line 755 of file float.c.

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

References float4_div(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4eq()

Datum float4eq ( PG_FUNCTION_ARGS  )

Definition at line 826 of file float.c.

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

References float4_eq(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4ge()

Datum float4ge ( PG_FUNCTION_ARGS  )

Definition at line 871 of file float.c.

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

References float4_ge(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4gt()

Datum float4gt ( PG_FUNCTION_ARGS  )

Definition at line 862 of file float.c.

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

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 
167  PG_RETURN_FLOAT4(float4in_internal(num, NULL, "real", num,
168  fcinfo->context));
169 }
float4 float4in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition: float.c:182
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277

References float4in_internal(), PG_GETARG_CSTRING, and PG_RETURN_FLOAT4.

Referenced by numeric_float4().

◆ float4in_internal()

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

Definition at line 182 of file float.c.

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

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

Referenced by float4in().

◆ float4larger()

Datum float4larger ( PG_FUNCTION_ARGS  )

Definition at line 620 of file float.c.

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

References float4_gt(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4le()

Datum float4le ( PG_FUNCTION_ARGS  )

Definition at line 853 of file float.c.

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

References float4_le(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4lt()

Datum float4lt ( PG_FUNCTION_ARGS  )

Definition at line 844 of file float.c.

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

References float4_lt(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4mi()

Datum float4mi ( PG_FUNCTION_ARGS  )

Definition at line 737 of file float.c.

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

References float4_mi(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4mul()

Datum float4mul ( PG_FUNCTION_ARGS  )

Definition at line 746 of file float.c.

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

References float4_mul(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4ne()

Datum float4ne ( PG_FUNCTION_ARGS  )

Definition at line 835 of file float.c.

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

References float4_ne(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4out()

Datum float4out ( PG_FUNCTION_ARGS  )

Definition at line 319 of file float.c.

320 {
321  float4 num = PG_GETARG_FLOAT4(0);
322  char *ascii = (char *) palloc(32);
323  int ndig = FLT_DIG + extra_float_digits;
324 
325  if (extra_float_digits > 0)
326  {
329  }
330 
331  (void) pg_strfromd(ascii, 32, ndig, num);
333 }
int float_to_shortest_decimal_buf(float f, char *result)
Definition: f2s.c:780
int extra_float_digits
Definition: float.c:43
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
void * palloc(Size size)
Definition: mcxt.c:1210
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 728 of file float.c.

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

References float4_pl(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4recv()

Datum float4recv ( PG_FUNCTION_ARGS  )

Definition at line 339 of file float.c.

340 {
342 
344 }
static char * buf
Definition: pg_test_fsync.c:67
float4 pq_getmsgfloat4(StringInfo msg)
Definition: pqformat.c:472
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 350 of file float.c.

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

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

◆ float4smaller()

Datum float4smaller ( PG_FUNCTION_ARGS  )

Definition at line 634 of file float.c.

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

References float4_lt(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4um()

Datum float4um ( PG_FUNCTION_ARGS  )

Definition at line 602 of file float.c.

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

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4up()

Datum float4up ( PG_FUNCTION_ARGS  )

Definition at line 612 of file float.c.

613 {
615 
617 }
void * arg

References arg, PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float84div()

Datum float84div ( PG_FUNCTION_ARGS  )

Definition at line 3942 of file float.c.

3943 {
3944  float8 arg1 = PG_GETARG_FLOAT8(0);
3945  float4 arg2 = PG_GETARG_FLOAT4(1);
3946 
3947  PG_RETURN_FLOAT8(float8_div(arg1, (float8) arg2));
3948 }

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

◆ float84eq()

Datum float84eq ( PG_FUNCTION_ARGS  )

Definition at line 4017 of file float.c.

4018 {
4019  float8 arg1 = PG_GETARG_FLOAT8(0);
4020  float4 arg2 = PG_GETARG_FLOAT4(1);
4021 
4022  PG_RETURN_BOOL(float8_eq(arg1, (float8) arg2));
4023 }

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

◆ float84ge()

Datum float84ge ( PG_FUNCTION_ARGS  )

Definition at line 4062 of file float.c.

4063 {
4064  float8 arg1 = PG_GETARG_FLOAT8(0);
4065  float4 arg2 = PG_GETARG_FLOAT4(1);
4066 
4067  PG_RETURN_BOOL(float8_ge(arg1, (float8) arg2));
4068 }

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

◆ float84gt()

Datum float84gt ( PG_FUNCTION_ARGS  )

Definition at line 4053 of file float.c.

4054 {
4055  float8 arg1 = PG_GETARG_FLOAT8(0);
4056  float4 arg2 = PG_GETARG_FLOAT4(1);
4057 
4058  PG_RETURN_BOOL(float8_gt(arg1, (float8) arg2));
4059 }

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

◆ float84le()

Datum float84le ( PG_FUNCTION_ARGS  )

Definition at line 4044 of file float.c.

4045 {
4046  float8 arg1 = PG_GETARG_FLOAT8(0);
4047  float4 arg2 = PG_GETARG_FLOAT4(1);
4048 
4049  PG_RETURN_BOOL(float8_le(arg1, (float8) arg2));
4050 }

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

◆ float84lt()

Datum float84lt ( PG_FUNCTION_ARGS  )

Definition at line 4035 of file float.c.

4036 {
4037  float8 arg1 = PG_GETARG_FLOAT8(0);
4038  float4 arg2 = PG_GETARG_FLOAT4(1);
4039 
4040  PG_RETURN_BOOL(float8_lt(arg1, (float8) arg2));
4041 }

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

◆ float84mi()

Datum float84mi ( PG_FUNCTION_ARGS  )

Definition at line 3924 of file float.c.

3925 {
3926  float8 arg1 = PG_GETARG_FLOAT8(0);
3927  float4 arg2 = PG_GETARG_FLOAT4(1);
3928 
3929  PG_RETURN_FLOAT8(float8_mi(arg1, (float8) arg2));
3930 }

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

◆ float84mul()

Datum float84mul ( PG_FUNCTION_ARGS  )

Definition at line 3933 of file float.c.

3934 {
3935  float8 arg1 = PG_GETARG_FLOAT8(0);
3936  float4 arg2 = PG_GETARG_FLOAT4(1);
3937 
3938  PG_RETURN_FLOAT8(float8_mul(arg1, (float8) arg2));
3939 }

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

◆ float84ne()

Datum float84ne ( PG_FUNCTION_ARGS  )

Definition at line 4026 of file float.c.

4027 {
4028  float8 arg1 = PG_GETARG_FLOAT8(0);
4029  float4 arg2 = PG_GETARG_FLOAT4(1);
4030 
4031  PG_RETURN_BOOL(float8_ne(arg1, (float8) arg2));
4032 }

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

◆ float84pl()

Datum float84pl ( PG_FUNCTION_ARGS  )

Definition at line 3915 of file float.c.

3916 {
3917  float8 arg1 = PG_GETARG_FLOAT8(0);
3918  float4 arg2 = PG_GETARG_FLOAT4(1);
3919 
3920  PG_RETURN_FLOAT8(float8_pl(arg1, (float8) arg2));
3921 }

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

◆ float8_accum()

Datum float8_accum ( PG_FUNCTION_ARGS  )

Definition at line 3046 of file float.c.

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

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

3215 {
3216  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3217  float8 *transvalues;
3218  float8 N,
3219  Sx;
3220 
3221  transvalues = check_float8_array(transarray, "float8_avg", 3);
3222  N = transvalues[0];
3223  Sx = transvalues[1];
3224  /* ignore Sxx */
3225 
3226  /* SQL defines AVG of no values to be NULL */
3227  if (N == 0.0)
3228  PG_RETURN_NULL();
3229 
3230  PG_RETURN_FLOAT8(Sx / N);
3231 }
#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 910 of file float.c.

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

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

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

◆ float8_combine()

Datum float8_combine ( PG_FUNCTION_ARGS  )

Definition at line 2952 of file float.c.

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

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

3741 {
3742  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3743  float8 *transvalues;
3744  float8 N,
3745  Sxx,
3746  Syy,
3747  Sxy;
3748 
3749  transvalues = check_float8_array(transarray, "float8_corr", 6);
3750  N = transvalues[0];
3751  Sxx = transvalues[2];
3752  Syy = transvalues[4];
3753  Sxy = transvalues[5];
3754 
3755  /* if N is 0 we should return NULL */
3756  if (N < 1.0)
3757  PG_RETURN_NULL();
3758 
3759  /* Note that Sxx and Syy are guaranteed to be non-negative */
3760 
3761  /* per spec, return NULL for horizontal and vertical lines */
3762  if (Sxx == 0 || Syy == 0)
3763  PG_RETURN_NULL();
3764 
3765  PG_RETURN_FLOAT8(Sxy / sqrt(Sxx * Syy));
3766 }

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

3703 {
3704  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3705  float8 *transvalues;
3706  float8 N,
3707  Sxy;
3708 
3709  transvalues = check_float8_array(transarray, "float8_covar_pop", 6);
3710  N = transvalues[0];
3711  Sxy = transvalues[5];
3712 
3713  /* if N is 0 we should return NULL */
3714  if (N < 1.0)
3715  PG_RETURN_NULL();
3716 
3717  PG_RETURN_FLOAT8(Sxy / N);
3718 }

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

3722 {
3723  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3724  float8 *transvalues;
3725  float8 N,
3726  Sxy;
3727 
3728  transvalues = check_float8_array(transarray, "float8_covar_samp", 6);
3729  N = transvalues[0];
3730  Sxy = transvalues[5];
3731 
3732  /* if N is <= 1 we should return NULL */
3733  if (N < 2.0)
3734  PG_RETURN_NULL();
3735 
3736  PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3737 }

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

3344 {
3345  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3346  float8 newvalY = PG_GETARG_FLOAT8(1);
3347  float8 newvalX = PG_GETARG_FLOAT8(2);
3348  float8 *transvalues;
3349  float8 N,
3350  Sx,
3351  Sxx,
3352  Sy,
3353  Syy,
3354  Sxy,
3355  tmpX,
3356  tmpY,
3357  scale;
3358 
3359  transvalues = check_float8_array(transarray, "float8_regr_accum", 6);
3360  N = transvalues[0];
3361  Sx = transvalues[1];
3362  Sxx = transvalues[2];
3363  Sy = transvalues[3];
3364  Syy = transvalues[4];
3365  Sxy = transvalues[5];
3366 
3367  /*
3368  * Use the Youngs-Cramer algorithm to incorporate the new values into the
3369  * transition values.
3370  */
3371  N += 1.0;
3372  Sx += newvalX;
3373  Sy += newvalY;
3374  if (transvalues[0] > 0.0)
3375  {
3376  tmpX = newvalX * N - Sx;
3377  tmpY = newvalY * N - Sy;
3378  scale = 1.0 / (N * transvalues[0]);
3379  Sxx += tmpX * tmpX * scale;
3380  Syy += tmpY * tmpY * scale;
3381  Sxy += tmpX * tmpY * scale;
3382 
3383  /*
3384  * Overflow check. We only report an overflow error when finite
3385  * inputs lead to infinite results. Note also that Sxx, Syy and Sxy
3386  * should be NaN if any of the relevant inputs are infinite, so we
3387  * intentionally prevent them from becoming infinite.
3388  */
3389  if (isinf(Sx) || isinf(Sxx) || isinf(Sy) || isinf(Syy) || isinf(Sxy))
3390  {
3391  if (((isinf(Sx) || isinf(Sxx)) &&
3392  !isinf(transvalues[1]) && !isinf(newvalX)) ||
3393  ((isinf(Sy) || isinf(Syy)) &&
3394  !isinf(transvalues[3]) && !isinf(newvalY)) ||
3395  (isinf(Sxy) &&
3396  !isinf(transvalues[1]) && !isinf(newvalX) &&
3397  !isinf(transvalues[3]) && !isinf(newvalY)))
3399 
3400  if (isinf(Sxx))
3401  Sxx = get_float8_nan();
3402  if (isinf(Syy))
3403  Syy = get_float8_nan();
3404  if (isinf(Sxy))
3405  Sxy = get_float8_nan();
3406  }
3407  }
3408  else
3409  {
3410  /*
3411  * At the first input, we normally can leave Sxx et al as 0. However,
3412  * if the first input is Inf or NaN, we'd better force the dependent
3413  * sums to NaN; otherwise we will falsely report variance zero when
3414  * there are no more inputs.
3415  */
3416  if (isnan(newvalX) || isinf(newvalX))
3417  Sxx = Sxy = get_float8_nan();
3418  if (isnan(newvalY) || isinf(newvalY))
3419  Syy = Sxy = get_float8_nan();
3420  }
3421 
3422  /*
3423  * If we're invoked as an aggregate, we can cheat and modify our first
3424  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3425  * new array with the updated transition data and return it.
3426  */
3427  if (AggCheckCallContext(fcinfo, NULL))
3428  {
3429  transvalues[0] = N;
3430  transvalues[1] = Sx;
3431  transvalues[2] = Sxx;
3432  transvalues[3] = Sy;
3433  transvalues[4] = Syy;
3434  transvalues[5] = Sxy;
3435 
3436  PG_RETURN_ARRAYTYPE_P(transarray);
3437  }
3438  else
3439  {
3440  Datum transdatums[6];
3441  ArrayType *result;
3442 
3443  transdatums[0] = Float8GetDatumFast(N);
3444  transdatums[1] = Float8GetDatumFast(Sx);
3445  transdatums[2] = Float8GetDatumFast(Sxx);
3446  transdatums[3] = Float8GetDatumFast(Sy);
3447  transdatums[4] = Float8GetDatumFast(Syy);
3448  transdatums[5] = Float8GetDatumFast(Sxy);
3449 
3450  result = construct_array(transdatums, 6,
3451  FLOAT8OID,
3452  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3453 
3454  PG_RETURN_ARRAYTYPE_P(result);
3455  }
3456 }
int scale
Definition: pgbench.c:191

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

3665 {
3666  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3667  float8 *transvalues;
3668  float8 N,
3669  Sx;
3670 
3671  transvalues = check_float8_array(transarray, "float8_regr_avgx", 6);
3672  N = transvalues[0];
3673  Sx = transvalues[1];
3674 
3675  /* if N is 0 we should return NULL */
3676  if (N < 1.0)
3677  PG_RETURN_NULL();
3678 
3679  PG_RETURN_FLOAT8(Sx / N);
3680 }

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

3684 {
3685  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3686  float8 *transvalues;
3687  float8 N,
3688  Sy;
3689 
3690  transvalues = check_float8_array(transarray, "float8_regr_avgy", 6);
3691  N = transvalues[0];
3692  Sy = transvalues[3];
3693 
3694  /* if N is 0 we should return NULL */
3695  if (N < 1.0)
3696  PG_RETURN_NULL();
3697 
3698  PG_RETURN_FLOAT8(Sy / N);
3699 }

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

3468 {
3469  ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
3470  ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
3471  float8 *transvalues1;
3472  float8 *transvalues2;
3473  float8 N1,
3474  Sx1,
3475  Sxx1,
3476  Sy1,
3477  Syy1,
3478  Sxy1,
3479  N2,
3480  Sx2,
3481  Sxx2,
3482  Sy2,
3483  Syy2,
3484  Sxy2,
3485  tmp1,
3486  tmp2,
3487  N,
3488  Sx,
3489  Sxx,
3490  Sy,
3491  Syy,
3492  Sxy;
3493 
3494  transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 6);
3495  transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 6);
3496 
3497  N1 = transvalues1[0];
3498  Sx1 = transvalues1[1];
3499  Sxx1 = transvalues1[2];
3500  Sy1 = transvalues1[3];
3501  Syy1 = transvalues1[4];
3502  Sxy1 = transvalues1[5];
3503 
3504  N2 = transvalues2[0];
3505  Sx2 = transvalues2[1];
3506  Sxx2 = transvalues2[2];
3507  Sy2 = transvalues2[3];
3508  Syy2 = transvalues2[4];
3509  Sxy2 = transvalues2[5];
3510 
3511  /*--------------------
3512  * The transition values combine using a generalization of the
3513  * Youngs-Cramer algorithm as follows:
3514  *
3515  * N = N1 + N2
3516  * Sx = Sx1 + Sx2
3517  * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N
3518  * Sy = Sy1 + Sy2
3519  * Syy = Syy1 + Syy2 + N1 * N2 * (Sy1/N1 - Sy2/N2)^2 / N
3520  * Sxy = Sxy1 + Sxy2 + N1 * N2 * (Sx1/N1 - Sx2/N2) * (Sy1/N1 - Sy2/N2) / N
3521  *
3522  * It's worth handling the special cases N1 = 0 and N2 = 0 separately
3523  * since those cases are trivial, and we then don't need to worry about
3524  * division-by-zero errors in the general case.
3525  *--------------------
3526  */
3527  if (N1 == 0.0)
3528  {
3529  N = N2;
3530  Sx = Sx2;
3531  Sxx = Sxx2;
3532  Sy = Sy2;
3533  Syy = Syy2;
3534  Sxy = Sxy2;
3535  }
3536  else if (N2 == 0.0)
3537  {
3538  N = N1;
3539  Sx = Sx1;
3540  Sxx = Sxx1;
3541  Sy = Sy1;
3542  Syy = Syy1;
3543  Sxy = Sxy1;
3544  }
3545  else
3546  {
3547  N = N1 + N2;
3548  Sx = float8_pl(Sx1, Sx2);
3549  tmp1 = Sx1 / N1 - Sx2 / N2;
3550  Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp1 * tmp1 / N;
3551  if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3553  Sy = float8_pl(Sy1, Sy2);
3554  tmp2 = Sy1 / N1 - Sy2 / N2;
3555  Syy = Syy1 + Syy2 + N1 * N2 * tmp2 * tmp2 / N;
3556  if (unlikely(isinf(Syy)) && !isinf(Syy1) && !isinf(Syy2))
3558  Sxy = Sxy1 + Sxy2 + N1 * N2 * tmp1 * tmp2 / N;
3559  if (unlikely(isinf(Sxy)) && !isinf(Sxy1) && !isinf(Sxy2))
3561  }
3562 
3563  /*
3564  * If we're invoked as an aggregate, we can cheat and modify our first
3565  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3566  * new array with the updated transition data and return it.
3567  */
3568  if (AggCheckCallContext(fcinfo, NULL))
3569  {
3570  transvalues1[0] = N;
3571  transvalues1[1] = Sx;
3572  transvalues1[2] = Sxx;
3573  transvalues1[3] = Sy;
3574  transvalues1[4] = Syy;
3575  transvalues1[5] = Sxy;
3576 
3577  PG_RETURN_ARRAYTYPE_P(transarray1);
3578  }
3579  else
3580  {
3581  Datum transdatums[6];
3582  ArrayType *result;
3583 
3584  transdatums[0] = Float8GetDatumFast(N);
3585  transdatums[1] = Float8GetDatumFast(Sx);
3586  transdatums[2] = Float8GetDatumFast(Sxx);
3587  transdatums[3] = Float8GetDatumFast(Sy);
3588  transdatums[4] = Float8GetDatumFast(Syy);
3589  transdatums[5] = Float8GetDatumFast(Sxy);
3590 
3591  result = construct_array(transdatums, 6,
3592  FLOAT8OID,
3593  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3594 
3595  PG_RETURN_ARRAYTYPE_P(result);
3596  }
3597 }

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

3830 {
3831  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3832  float8 *transvalues;
3833  float8 N,
3834  Sx,
3835  Sxx,
3836  Sy,
3837  Sxy;
3838 
3839  transvalues = check_float8_array(transarray, "float8_regr_intercept", 6);
3840  N = transvalues[0];
3841  Sx = transvalues[1];
3842  Sxx = transvalues[2];
3843  Sy = transvalues[3];
3844  Sxy = transvalues[5];
3845 
3846  /* if N is 0 we should return NULL */
3847  if (N < 1.0)
3848  PG_RETURN_NULL();
3849 
3850  /* Note that Sxx is guaranteed to be non-negative */
3851 
3852  /* per spec, return NULL for a vertical line */
3853  if (Sxx == 0)
3854  PG_RETURN_NULL();
3855 
3856  PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
3857 }

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

3770 {
3771  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3772  float8 *transvalues;
3773  float8 N,
3774  Sxx,
3775  Syy,
3776  Sxy;
3777 
3778  transvalues = check_float8_array(transarray, "float8_regr_r2", 6);
3779  N = transvalues[0];
3780  Sxx = transvalues[2];
3781  Syy = transvalues[4];
3782  Sxy = transvalues[5];
3783 
3784  /* if N is 0 we should return NULL */
3785  if (N < 1.0)
3786  PG_RETURN_NULL();
3787 
3788  /* Note that Sxx and Syy are guaranteed to be non-negative */
3789 
3790  /* per spec, return NULL for a vertical line */
3791  if (Sxx == 0)
3792  PG_RETURN_NULL();
3793 
3794  /* per spec, return 1.0 for a horizontal line */
3795  if (Syy == 0)
3796  PG_RETURN_FLOAT8(1.0);
3797 
3798  PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3799 }

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

3803 {
3804  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3805  float8 *transvalues;
3806  float8 N,
3807  Sxx,
3808  Sxy;
3809 
3810  transvalues = check_float8_array(transarray, "float8_regr_slope", 6);
3811  N = transvalues[0];
3812  Sxx = transvalues[2];
3813  Sxy = transvalues[5];
3814 
3815  /* if N is 0 we should return NULL */
3816  if (N < 1.0)
3817  PG_RETURN_NULL();
3818 
3819  /* Note that Sxx is guaranteed to be non-negative */
3820 
3821  /* per spec, return NULL for a vertical line */
3822  if (Sxx == 0)
3823  PG_RETURN_NULL();
3824 
3825  PG_RETURN_FLOAT8(Sxy / Sxx);
3826 }

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

3602 {
3603  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3604  float8 *transvalues;
3605  float8 N,
3606  Sxx;
3607 
3608  transvalues = check_float8_array(transarray, "float8_regr_sxx", 6);
3609  N = transvalues[0];
3610  Sxx = transvalues[2];
3611 
3612  /* if N is 0 we should return NULL */
3613  if (N < 1.0)
3614  PG_RETURN_NULL();
3615 
3616  /* Note that Sxx is guaranteed to be non-negative */
3617 
3618  PG_RETURN_FLOAT8(Sxx);
3619 }

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

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

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

3623 {
3624  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3625  float8 *transvalues;
3626  float8 N,
3627  Syy;
3628 
3629  transvalues = check_float8_array(transarray, "float8_regr_syy", 6);
3630  N = transvalues[0];
3631  Syy = transvalues[4];
3632 
3633  /* if N is 0 we should return NULL */
3634  if (N < 1.0)
3635  PG_RETURN_NULL();
3636 
3637  /* Note that Syy is guaranteed to be non-negative */
3638 
3639  PG_RETURN_FLOAT8(Syy);
3640 }

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

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

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

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

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

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

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

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

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

◆ float8abs()

Datum float8abs ( PG_FUNCTION_ARGS  )

Definition at line 657 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8div()

Datum float8div ( PG_FUNCTION_ARGS  )

Definition at line 797 of file float.c.

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

References float8_div(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8eq()

Datum float8eq ( PG_FUNCTION_ARGS  )

Definition at line 920 of file float.c.

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

References float8_eq(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8ge()

Datum float8ge ( PG_FUNCTION_ARGS  )

Definition at line 965 of file float.c.

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

References float8_ge(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8gt()

Datum float8gt ( PG_FUNCTION_ARGS  )

Definition at line 956 of file float.c.

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

References float8_gt(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8in()

Datum float8in ( PG_FUNCTION_ARGS  )

Definition at line 364 of file float.c.

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

References float8in_internal(), PG_GETARG_CSTRING, and PG_RETURN_FLOAT8.

Referenced by numeric_float8().

◆ float8in_internal()

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

Definition at line 395 of file float.c.

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

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

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

◆ float8larger()

Datum float8larger ( PG_FUNCTION_ARGS  )

Definition at line 687 of file float.c.

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

References float8_gt(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8le()

Datum float8le ( PG_FUNCTION_ARGS  )

Definition at line 947 of file float.c.

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

References float8_le(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8lt()

Datum float8lt ( PG_FUNCTION_ARGS  )

Definition at line 938 of file float.c.

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

References float8_lt(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8mi()

Datum float8mi ( PG_FUNCTION_ARGS  )

Definition at line 779 of file float.c.

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

References float8_mi(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8mul()

Datum float8mul ( PG_FUNCTION_ARGS  )

Definition at line 788 of file float.c.

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

References float8_mul(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8ne()

Datum float8ne ( PG_FUNCTION_ARGS  )

Definition at line 929 of file float.c.

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

References float8_ne(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8out()

Datum float8out ( PG_FUNCTION_ARGS  )

Definition at line 522 of file float.c.

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

References float8out_internal(), PG_GETARG_FLOAT8, and PG_RETURN_CSTRING.

◆ float8out_internal()

char* float8out_internal ( double  num)

Definition at line 537 of file float.c.

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

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

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

◆ float8pl()

Datum float8pl ( PG_FUNCTION_ARGS  )

Definition at line 770 of file float.c.

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

References float8_pl(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8recv()

Datum float8recv ( PG_FUNCTION_ARGS  )

Definition at line 556 of file float.c.

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

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

◆ float8send()

Datum float8send ( PG_FUNCTION_ARGS  )

Definition at line 567 of file float.c.

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

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

◆ float8smaller()

Datum float8smaller ( PG_FUNCTION_ARGS  )

Definition at line 701 of file float.c.

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

References float8_lt(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8um()

Datum float8um ( PG_FUNCTION_ARGS  )

Definition at line 669 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8up()

Datum float8up ( PG_FUNCTION_ARGS  )

Definition at line 679 of file float.c.

680 {
682 
684 }

References arg, PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float_overflow_error()

◆ float_underflow_error()

pg_noinline void float_underflow_error ( void  )

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

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

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT8.

◆ ftoi2()

Datum ftoi2 ( PG_FUNCTION_ARGS  )

Definition at line 1313 of file float.c.

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

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

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

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

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

References PG_GETARG_INT16, and PG_RETURN_FLOAT8.

◆ i2tof()

Datum i2tof ( PG_FUNCTION_ARGS  )

Definition at line 1350 of file float.c.

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

References PG_GETARG_INT16, and PG_RETURN_FLOAT4.

◆ i4tod()

Datum i4tod ( PG_FUNCTION_ARGS  )

Definition at line 1264 of file float.c.

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

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

◆ i4tof()

Datum i4tof ( PG_FUNCTION_ARGS  )

Definition at line 1338 of file float.c.

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

References PG_GETARG_INT32, and PG_RETURN_FLOAT4.

◆ in_range_float4_float8()

Datum in_range_float4_float8 ( PG_FUNCTION_ARGS  )

Definition at line 1103 of file float.c.

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

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

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

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

◆ init_degree_constants()

static void init_degree_constants ( void  )
static

Definition at line 2019 of file float.c.

2020 {
2023  asin_0_5 = asin(degree_c_one_half);
2024  acos_0_5 = acos(degree_c_one_half);
2025  atan_1_0 = atan(degree_c_one);
2028  degree_consts_set = true;
2029 }
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.

◆ initialize_drandom_seed()

static void initialize_drandom_seed ( void  )
static

Definition at line 2796 of file float.c.

2797 {
2798  /* Initialize random seed, if not done yet in this process */
2799  if (unlikely(!drandom_seed_set))
2800  {
2801  /*
2802  * If possible, initialize the seed using high-quality random bits.
2803  * Should that fail for some reason, we fall back on a lower-quality
2804  * seed based on current time and PID.
2805  */
2807  {
2809  uint64 iseed;
2810 
2811  /* Mix the PID with the most predictable bits of the timestamp */
2812  iseed = (uint64) now ^ ((uint64) MyProcPid << 32);
2813  pg_prng_seed(&drandom_seed, iseed);
2814  }
2815  drandom_seed_set = true;
2816  }
2817 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1582
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1546
int64 TimestampTz
Definition: timestamp.h:39
static bool drandom_seed_set
Definition: float.c:68
int MyProcPid
Definition: globals.c:44
void pg_prng_seed(pg_prng_state *state, uint64 seed)
Definition: pg_prng.c:89
#define pg_prng_strong_seed(state)
Definition: pg_prng.h:46

References drandom_seed, drandom_seed_set, GetCurrentTimestamp(), MyProcPid, now(), pg_prng_seed(), pg_prng_strong_seed, and unlikely.

Referenced by drandom(), and drandom_normal().

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

2584 {
2585  float8 arg1 = PG_GETARG_FLOAT8(0);
2586 
2588 }

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

◆ setseed()

Datum setseed ( PG_FUNCTION_ARGS  )

Definition at line 2861 of file float.c.

2862 {
2863  float8 seed = PG_GETARG_FLOAT8(0);
2864 
2865  if (seed < -1 || seed > 1 || isnan(seed))
2866  ereport(ERROR,
2867  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2868  errmsg("setseed parameter %g is out of allowed range [-1,1]",
2869  seed)));
2870 
2871  pg_prng_fseed(&drandom_seed, seed);
2872  drandom_seed_set = true;
2873 
2874  PG_RETURN_VOID();
2875 }
void pg_prng_fseed(pg_prng_state *state, double fseed)
Definition: pg_prng.c:102

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

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

References RADIANS_PER_DEGREE, sin_30, and x.

Referenced by cosd_q1(), and sind_q1().

◆ sind_q1()

static double sind_q1 ( double  x)
static

Definition at line 2279 of file float.c.

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

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

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

◆ width_bucket_float8()

Datum width_bucket_float8 ( PG_FUNCTION_ARGS  )

Definition at line 4085 of file float.c.

4086 {
4087  float8 operand = PG_GETARG_FLOAT8(0);
4088  float8 bound1 = PG_GETARG_FLOAT8(1);
4089  float8 bound2 = PG_GETARG_FLOAT8(2);
4090  int32 count = PG_GETARG_INT32(3);
4091  int32 result;
4092 
4093  if (count <= 0)
4094  ereport(ERROR,
4095  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4096  errmsg("count must be greater than zero")));
4097 
4098  if (isnan(operand) || isnan(bound1) || isnan(bound2))
4099  ereport(ERROR,
4100  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4101  errmsg("operand, lower bound, and upper bound cannot be NaN")));
4102 
4103  /* Note that we allow "operand" to be infinite */
4104  if (isinf(bound1) || isinf(bound2))
4105  ereport(ERROR,
4106  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4107  errmsg("lower and upper bounds must be finite")));
4108 
4109  if (bound1 < bound2)
4110  {
4111  if (operand < bound1)
4112  result = 0;
4113  else if (operand >= bound2)
4114  {
4115  if (pg_add_s32_overflow(count, 1, &result))
4116  ereport(ERROR,
4117  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4118  errmsg("integer out of range")));
4119  }
4120  else
4121  {
4122  if (!isinf(bound2 - bound1))
4123  {
4124  /* The quotient is surely in [0,1], so this can't overflow */
4125  result = count * ((operand - bound1) / (bound2 - bound1));
4126  }
4127  else
4128  {
4129  /*
4130  * We get here if bound2 - bound1 overflows DBL_MAX. Since
4131  * both bounds are finite, their difference can't exceed twice
4132  * DBL_MAX; so we can perform the computation without overflow
4133  * by dividing all the inputs by 2. That should be exact too,
4134  * except in the case where a very small operand underflows to
4135  * zero, which would have negligible impact on the result
4136  * given such large bounds.
4137  */
4138  result = count * ((operand / 2 - bound1 / 2) / (bound2 / 2 - bound1 / 2));
4139  }
4140  /* The quotient could round to 1.0, which would be a lie */
4141  if (result >= count)
4142  result = count - 1;
4143  /* Having done that, we can add 1 without fear of overflow */
4144  result++;
4145  }
4146  }
4147  else if (bound1 > bound2)
4148  {
4149  if (operand > bound1)
4150  result = 0;
4151  else if (operand <= bound2)
4152  {
4153  if (pg_add_s32_overflow(count, 1, &result))
4154  ereport(ERROR,
4155  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4156  errmsg("integer out of range")));
4157  }
4158  else
4159  {
4160  if (!isinf(bound1 - bound2))
4161  result = count * ((bound1 - operand) / (bound1 - bound2));
4162  else
4163  result = count * ((bound1 / 2 - operand / 2) / (bound1 / 2 - bound2 / 2));
4164  if (result >= count)
4165  result = count - 1;
4166  result++;
4167  }
4168  }
4169  else
4170  {
4171  ereport(ERROR,
4172  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4173  errmsg("lower bound cannot equal upper bound")));
4174  result = 0; /* keep the compiler quiet */
4175  }
4176 
4177  PG_RETURN_INT32(result);
4178 }
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(), drandom_normal(), initialize_drandom_seed(), and setseed().

◆ drandom_seed_set

bool drandom_seed_set = false
static

Definition at line 68 of file float.c.

Referenced by initialize_drandom_seed(), 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().