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

Function Documentation

◆ acosd_q1()

static double acosd_q1 ( double  x)
static

Definition at line 2080 of file float.c.

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

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

References acos_0_5, asin_0_5, and x.

Referenced by dacosd(), and dasind().

◆ btfloat48cmp()

Datum btfloat48cmp ( PG_FUNCTION_ARGS  )

Definition at line 1000 of file float.c.

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

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

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

889 {
890  float4 arg1 = DatumGetFloat4(x);
891  float4 arg2 = DatumGetFloat4(y);
892 
893  return float4_cmp_internal(arg1, arg2);
894 }
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 897 of file float.c.

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

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

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

◆ btfloat8cmp()

Datum btfloat8cmp ( PG_FUNCTION_ARGS  )

Definition at line 973 of file float.c.

974 {
975  float8 arg1 = PG_GETARG_FLOAT8(0);
976  float8 arg2 = PG_GETARG_FLOAT8(1);
977 
979 }

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

983 {
984  float8 arg1 = DatumGetFloat8(x);
985  float8 arg2 = DatumGetFloat8(y);
986 
987  return float8_cmp_internal(arg1, arg2);
988 }
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 991 of file float.c.

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

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

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

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

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

◆ cosd_0_to_60()

static double cosd_0_to_60 ( double  x)
static

Definition at line 2265 of file float.c.

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

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

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

1755 {
1756  float8 arg1 = PG_GETARG_FLOAT8(0);
1757  float8 result;
1758 
1759  /* Per the POSIX spec, return NaN if the input is NaN */
1760  if (isnan(arg1))
1762 
1763  /*
1764  * The principal branch of the inverse cosine function maps values in the
1765  * range [-1, 1] to values in the range [0, Pi], so we should reject any
1766  * inputs outside that range and the result will always be finite.
1767  */
1768  if (arg1 < -1.0 || arg1 > 1.0)
1769  ereport(ERROR,
1770  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1771  errmsg("input is out of range")));
1772 
1773  result = acos(arg1);
1774  if (unlikely(isinf(result)))
1776 
1777  PG_RETURN_FLOAT8(result);
1778 }
#define unlikely(x)
Definition: c.h:298
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#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 2107 of file float.c.

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

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

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

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

◆ dasin()

Datum dasin ( PG_FUNCTION_ARGS  )

Definition at line 1785 of file float.c.

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

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

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

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

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ datan()

Datum datan ( PG_FUNCTION_ARGS  )

Definition at line 1816 of file float.c.

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

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

◆ datan2()

Datum datan2 ( PG_FUNCTION_ARGS  )

Definition at line 1842 of file float.c.

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

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

◆ datan2d()

Datum datan2d ( PG_FUNCTION_ARGS  )

Definition at line 2213 of file float.c.

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

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

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

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

1470 {
1471  float8 arg1 = PG_GETARG_FLOAT8(0);
1472  float8 result;
1473 
1474  result = cbrt(arg1);
1475  if (unlikely(isinf(result)) && !isinf(arg1))
1477  if (unlikely(result == 0.0) && arg1 != 0.0)
1479 
1480  PG_RETURN_FLOAT8(result);
1481 }
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 1379 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dcos()

Datum dcos ( PG_FUNCTION_ARGS  )

Definition at line 1868 of file float.c.

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

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

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

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

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

◆ dcot()

Datum dcot ( PG_FUNCTION_ARGS  )

Definition at line 1909 of file float.c.

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

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

◆ dcotd()

Datum dcotd ( PG_FUNCTION_ARGS  )

Definition at line 2372 of file float.c.

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

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

2561 {
2562  float8 arg1 = PG_GETARG_FLOAT8(0);
2563 
2565 }
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 2751 of file float.c.

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

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

◆ derfc()

Datum derfc ( PG_FUNCTION_ARGS  )

Definition at line 2771 of file float.c.

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

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

◆ dexp()

Datum dexp ( PG_FUNCTION_ARGS  )

Definition at line 1643 of file float.c.

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

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

◆ dfloor()

Datum dfloor ( PG_FUNCTION_ARGS  )

Definition at line 1391 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dlog1()

Datum dlog1 ( PG_FUNCTION_ARGS  )

Definition at line 1689 of file float.c.

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

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

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

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

◆ dpi()

Definition at line 2572 of file float.c.

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

References M_PI, and PG_RETURN_FLOAT8.

◆ dpow()

Datum dpow ( PG_FUNCTION_ARGS  )

Definition at line 1488 of file float.c.

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

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

2823 {
2824  float8 result;
2825 
2827 
2828  /* pg_prng_double produces desired result range [0.0 - 1.0) */
2829  result = pg_prng_double(&drandom_seed);
2830 
2831  PG_RETURN_FLOAT8(result);
2832 }
static void initialize_drandom_seed(void)
Definition: float.c:2795
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 2838 of file float.c.

2839 {
2840  float8 mean = PG_GETARG_FLOAT8(0);
2841  float8 stddev = PG_GETARG_FLOAT8(1);
2842  float8 result,
2843  z;
2844 
2846 
2847  /* Get random value from standard normal(mean = 0.0, stddev = 1.0) */
2849  /* Transform the normal standard variable (z) */
2850  /* using the target normal distribution parameters */
2851  result = (stddev * z) + mean;
2852 
2853  PG_RETURN_FLOAT8(result);
2854 }
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 1367 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsign()

Datum dsign ( PG_FUNCTION_ARGS  )

Definition at line 1404 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsin()

Datum dsin ( PG_FUNCTION_ARGS  )

Definition at line 1937 of file float.c.

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

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

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

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

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

References get_float8_infinity(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ dsqrt()

Datum dsqrt ( PG_FUNCTION_ARGS  )

Definition at line 1445 of file float.c.

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

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

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

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

◆ dtand()

Datum dtand ( PG_FUNCTION_ARGS  )

Definition at line 2494 of file float.c.

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

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

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

◆ dtof()

Datum dtof ( PG_FUNCTION_ARGS  )

Definition at line 1194 of file float.c.

1195 {
1196  float8 num = PG_GETARG_FLOAT8(0);
1197  float4 result;
1198 
1199  result = (float4) num;
1200  if (unlikely(isinf(result)) && !isinf(num))
1202  if (unlikely(result == 0.0f) && num != 0.0)
1204 
1205  PG_RETURN_FLOAT4(result);
1206 }
#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 1238 of file float.c.

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

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

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

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float48div()

Datum float48div ( PG_FUNCTION_ARGS  )

Definition at line 3899 of file float.c.

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

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

◆ float48eq()

Datum float48eq ( PG_FUNCTION_ARGS  )

Definition at line 3959 of file float.c.

3960 {
3961  float4 arg1 = PG_GETARG_FLOAT4(0);
3962  float8 arg2 = PG_GETARG_FLOAT8(1);
3963 
3964  PG_RETURN_BOOL(float8_eq((float8) arg1, arg2));
3965 }
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 4004 of file float.c.

4005 {
4006  float4 arg1 = PG_GETARG_FLOAT4(0);
4007  float8 arg2 = PG_GETARG_FLOAT8(1);
4008 
4009  PG_RETURN_BOOL(float8_ge((float8) arg1, arg2));
4010 }
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 3995 of file float.c.

3996 {
3997  float4 arg1 = PG_GETARG_FLOAT4(0);
3998  float8 arg2 = PG_GETARG_FLOAT8(1);
3999 
4000  PG_RETURN_BOOL(float8_gt((float8) arg1, arg2));
4001 }
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 3986 of file float.c.

3987 {
3988  float4 arg1 = PG_GETARG_FLOAT4(0);
3989  float8 arg2 = PG_GETARG_FLOAT8(1);
3990 
3991  PG_RETURN_BOOL(float8_le((float8) arg1, arg2));
3992 }
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 3977 of file float.c.

3978 {
3979  float4 arg1 = PG_GETARG_FLOAT4(0);
3980  float8 arg2 = PG_GETARG_FLOAT8(1);
3981 
3982  PG_RETURN_BOOL(float8_lt((float8) arg1, arg2));
3983 }
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 3881 of file float.c.

3882 {
3883  float4 arg1 = PG_GETARG_FLOAT4(0);
3884  float8 arg2 = PG_GETARG_FLOAT8(1);
3885 
3886  PG_RETURN_FLOAT8(float8_mi((float8) arg1, arg2));
3887 }
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 3890 of file float.c.

3891 {
3892  float4 arg1 = PG_GETARG_FLOAT4(0);
3893  float8 arg2 = PG_GETARG_FLOAT8(1);
3894 
3895  PG_RETURN_FLOAT8(float8_mul((float8) arg1, arg2));
3896 }
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 3968 of file float.c.

3969 {
3970  float4 arg1 = PG_GETARG_FLOAT4(0);
3971  float8 arg2 = PG_GETARG_FLOAT8(1);
3972 
3973  PG_RETURN_BOOL(float8_ne((float8) arg1, arg2));
3974 }
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 3872 of file float.c.

3873 {
3874  float4 arg1 = PG_GETARG_FLOAT4(0);
3875  float8 arg2 = PG_GETARG_FLOAT8(1);
3876 
3877  PG_RETURN_FLOAT8(float8_pl((float8) arg1, arg2));
3878 }
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 3128 of file float.c.

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

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

◆ float4_cmp_internal()

int float4_cmp_internal ( float4  a,
float4  b 
)

Definition at line 815 of file float.c.

816 {
817  if (float4_gt(a, b))
818  return 1;
819  if (float4_lt(a, b))
820  return -1;
821  return 0;
822 }
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 590 of file float.c.

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

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4div()

Datum float4div ( PG_FUNCTION_ARGS  )

Definition at line 754 of file float.c.

755 {
756  float4 arg1 = PG_GETARG_FLOAT4(0);
757  float4 arg2 = PG_GETARG_FLOAT4(1);
758 
759  PG_RETURN_FLOAT4(float4_div(arg1, arg2));
760 }
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 825 of file float.c.

826 {
827  float4 arg1 = PG_GETARG_FLOAT4(0);
828  float4 arg2 = PG_GETARG_FLOAT4(1);
829 
830  PG_RETURN_BOOL(float4_eq(arg1, arg2));
831 }
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 870 of file float.c.

871 {
872  float4 arg1 = PG_GETARG_FLOAT4(0);
873  float4 arg2 = PG_GETARG_FLOAT4(1);
874 
875  PG_RETURN_BOOL(float4_ge(arg1, arg2));
876 }
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 861 of file float.c.

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

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

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

References float4_gt(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4le()

Datum float4le ( PG_FUNCTION_ARGS  )

Definition at line 852 of file float.c.

853 {
854  float4 arg1 = PG_GETARG_FLOAT4(0);
855  float4 arg2 = PG_GETARG_FLOAT4(1);
856 
857  PG_RETURN_BOOL(float4_le(arg1, arg2));
858 }
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 843 of file float.c.

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

References float4_lt(), PG_GETARG_FLOAT4, and PG_RETURN_BOOL.

◆ float4mi()

Datum float4mi ( PG_FUNCTION_ARGS  )

Definition at line 736 of file float.c.

737 {
738  float4 arg1 = PG_GETARG_FLOAT4(0);
739  float4 arg2 = PG_GETARG_FLOAT4(1);
740 
741  PG_RETURN_FLOAT4(float4_mi(arg1, arg2));
742 }
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 745 of file float.c.

746 {
747  float4 arg1 = PG_GETARG_FLOAT4(0);
748  float4 arg2 = PG_GETARG_FLOAT4(1);
749 
750  PG_RETURN_FLOAT4(float4_mul(arg1, arg2));
751 }
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 834 of file float.c.

835 {
836  float4 arg1 = PG_GETARG_FLOAT4(0);
837  float4 arg2 = PG_GETARG_FLOAT4(1);
838 
839  PG_RETURN_BOOL(float4_ne(arg1, arg2));
840 }
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 318 of file float.c.

319 {
320  float4 num = PG_GETARG_FLOAT4(0);
321  char *ascii = (char *) palloc(32);
322  int ndig = FLT_DIG + extra_float_digits;
323 
324  if (extra_float_digits > 0)
325  {
328  }
329 
330  (void) pg_strfromd(ascii, 32, ndig, num);
332 }
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:1304
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 727 of file float.c.

728 {
729  float4 arg1 = PG_GETARG_FLOAT4(0);
730  float4 arg2 = PG_GETARG_FLOAT4(1);
731 
732  PG_RETURN_FLOAT4(float4_pl(arg1, arg2));
733 }
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 338 of file float.c.

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

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

◆ float4send()

Datum float4send ( PG_FUNCTION_ARGS  )

Definition at line 349 of file float.c.

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

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

◆ float4smaller()

Datum float4smaller ( PG_FUNCTION_ARGS  )

Definition at line 633 of file float.c.

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

References float4_lt(), PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4um()

Datum float4um ( PG_FUNCTION_ARGS  )

Definition at line 601 of file float.c.

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

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float4up()

Datum float4up ( PG_FUNCTION_ARGS  )

Definition at line 611 of file float.c.

612 {
614 
616 }
void * arg

References arg, PG_GETARG_FLOAT4, and PG_RETURN_FLOAT4.

◆ float84div()

Datum float84div ( PG_FUNCTION_ARGS  )

Definition at line 3941 of file float.c.

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

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

◆ float84eq()

Datum float84eq ( PG_FUNCTION_ARGS  )

Definition at line 4016 of file float.c.

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

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

◆ float84ge()

Datum float84ge ( PG_FUNCTION_ARGS  )

Definition at line 4061 of file float.c.

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

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

◆ float84gt()

Datum float84gt ( PG_FUNCTION_ARGS  )

Definition at line 4052 of file float.c.

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

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

◆ float84le()

Datum float84le ( PG_FUNCTION_ARGS  )

Definition at line 4043 of file float.c.

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

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

◆ float84lt()

Datum float84lt ( PG_FUNCTION_ARGS  )

Definition at line 4034 of file float.c.

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

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

◆ float84mi()

Datum float84mi ( PG_FUNCTION_ARGS  )

Definition at line 3923 of file float.c.

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

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

◆ float84mul()

Datum float84mul ( PG_FUNCTION_ARGS  )

Definition at line 3932 of file float.c.

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

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

◆ float84ne()

Datum float84ne ( PG_FUNCTION_ARGS  )

Definition at line 4025 of file float.c.

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

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

◆ float84pl()

Datum float84pl ( PG_FUNCTION_ARGS  )

Definition at line 3914 of file float.c.

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

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

◆ float8_accum()

Datum float8_accum ( PG_FUNCTION_ARGS  )

Definition at line 3045 of file float.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

References AggCheckCallContext(), check_float8_array(), construct_array(), Float8GetDatumFast, FLOAT8PASSBYVAL, float_overflow_error(), get_float8_nan(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_FLOAT8, PG_RETURN_ARRAYTYPE_P, and scale.

◆ float8_regr_avgx()

Datum float8_regr_avgx ( PG_FUNCTION_ARGS  )

Definition at line 3663 of file float.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

◆ float8_var_pop()

Datum float8_var_pop ( PG_FUNCTION_ARGS  )

Definition at line 3233 of file float.c.

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

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

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

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

◆ float8abs()

Datum float8abs ( PG_FUNCTION_ARGS  )

Definition at line 656 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8div()

Datum float8div ( PG_FUNCTION_ARGS  )

Definition at line 796 of file float.c.

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

References float8_div(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8eq()

Datum float8eq ( PG_FUNCTION_ARGS  )

Definition at line 919 of file float.c.

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

References float8_eq(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8ge()

Datum float8ge ( PG_FUNCTION_ARGS  )

Definition at line 964 of file float.c.

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

References float8_ge(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8gt()

Datum float8gt ( PG_FUNCTION_ARGS  )

Definition at line 955 of file float.c.

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

References float8_gt(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8in()

Datum float8in ( PG_FUNCTION_ARGS  )

Definition at line 363 of file float.c.

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

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

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

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

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

References float8_gt(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8le()

Datum float8le ( PG_FUNCTION_ARGS  )

Definition at line 946 of file float.c.

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

References float8_le(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8lt()

Datum float8lt ( PG_FUNCTION_ARGS  )

Definition at line 937 of file float.c.

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

References float8_lt(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8mi()

Datum float8mi ( PG_FUNCTION_ARGS  )

Definition at line 778 of file float.c.

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

References float8_mi(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8mul()

Datum float8mul ( PG_FUNCTION_ARGS  )

Definition at line 787 of file float.c.

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

References float8_mul(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8ne()

Datum float8ne ( PG_FUNCTION_ARGS  )

Definition at line 928 of file float.c.

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

References float8_ne(), PG_GETARG_FLOAT8, and PG_RETURN_BOOL.

◆ float8out()

Datum float8out ( PG_FUNCTION_ARGS  )

Definition at line 521 of file float.c.

522 {
523  float8 num = PG_GETARG_FLOAT8(0);
524 
526 }
char * float8out_internal(double num)
Definition: float.c:536

References float8out_internal(), PG_GETARG_FLOAT8, and PG_RETURN_CSTRING.

◆ float8out_internal()

char* float8out_internal ( double  num)

Definition at line 536 of file float.c.

537 {
538  char *ascii = (char *) palloc(32);
539  int ndig = DBL_DIG + extra_float_digits;
540 
541  if (extra_float_digits > 0)
542  {
544  return ascii;
545  }
546 
547  (void) pg_strfromd(ascii, 32, ndig, num);
548  return ascii;
549 }
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 769 of file float.c.

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

References float8_pl(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8recv()

Datum float8recv ( PG_FUNCTION_ARGS  )

Definition at line 555 of file float.c.

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

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

◆ float8send()

Datum float8send ( PG_FUNCTION_ARGS  )

Definition at line 566 of file float.c.

567 {
568  float8 num = PG_GETARG_FLOAT8(0);
570 
572  pq_sendfloat8(&buf, num);
574 }
void pq_sendfloat8(StringInfo buf, float8 f)
Definition: pqformat.c:276

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

◆ float8smaller()

Datum float8smaller ( PG_FUNCTION_ARGS  )

Definition at line 700 of file float.c.

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

References float8_lt(), PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8um()

Datum float8um ( PG_FUNCTION_ARGS  )

Definition at line 668 of file float.c.

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

References PG_GETARG_FLOAT8, and PG_RETURN_FLOAT8.

◆ float8up()

Datum float8up ( PG_FUNCTION_ARGS  )

Definition at line 678 of file float.c.

679 {
681 
683 }

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

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

References PG_GETARG_FLOAT4, and PG_RETURN_FLOAT8.

◆ ftoi2()

Datum ftoi2 ( PG_FUNCTION_ARGS  )

Definition at line 1312 of file float.c.

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

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

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

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

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

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

References PG_GETARG_INT16, and PG_RETURN_FLOAT4.

◆ i4tod()

Datum i4tod ( PG_FUNCTION_ARGS  )

Definition at line 1263 of file float.c.

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

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

References PG_GETARG_INT32, and PG_RETURN_FLOAT4.

◆ in_range_float4_float8()

Datum in_range_float4_float8 ( PG_FUNCTION_ARGS  )

Definition at line 1102 of file float.c.

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

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

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

2019 {
2022  asin_0_5 = asin(degree_c_one_half);
2023  acos_0_5 = acos(degree_c_one_half);
2024  atan_1_0 = atan(degree_c_one);
2027  degree_consts_set = true;
2028 }
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 2795 of file float.c.

2796 {
2797  /* Initialize random seed, if not done yet in this process */
2798  if (unlikely(!drandom_seed_set))
2799  {
2800  /*
2801  * If possible, initialize the seed using high-quality random bits.
2802  * Should that fail for some reason, we fall back on a lower-quality
2803  * seed based on current time and PID.
2804  */
2806  {
2808  uint64 iseed;
2809 
2810  /* Mix the PID with the most predictable bits of the timestamp */
2811  iseed = (uint64) now ^ ((uint64) MyProcPid << 32);
2812  pg_prng_seed(&drandom_seed, iseed);
2813  }
2814  drandom_seed_set = true;
2815  }
2816 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1654
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1618
int64 TimestampTz
Definition: timestamp.h:39
static bool drandom_seed_set
Definition: float.c:68
int MyProcPid
Definition: globals.c:45
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 2582 of file float.c.

2583 {
2584  float8 arg1 = PG_GETARG_FLOAT8(0);
2585 
2587 }

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

◆ setseed()

Datum setseed ( PG_FUNCTION_ARGS  )

Definition at line 2860 of file float.c.

2861 {
2862  float8 seed = PG_GETARG_FLOAT8(0);
2863 
2864  if (seed < -1 || seed > 1 || isnan(seed))
2865  ereport(ERROR,
2866  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2867  errmsg("setseed parameter %g is out of allowed range [-1,1]",
2868  seed)));
2869 
2870  pg_prng_fseed(&drandom_seed, seed);
2871  drandom_seed_set = true;
2872 
2873  PG_RETURN_VOID();
2874 }
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 2251 of file float.c.

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

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

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

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

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