📄 float.c
字号:
sumX, sumX2, numerator; transvalues = check_float8_array(transarray, "float8_regr_sxx", 6); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); numerator = N * sumX2 - sumX * sumX; CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true); /* Watch out for roundoff error producing a negative numerator */ if (numerator <= 0.0) PG_RETURN_FLOAT8(0.0); PG_RETURN_FLOAT8(numerator / N);}Datumfloat8_regr_syy(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumY, sumY2, numerator; transvalues = check_float8_array(transarray, "float8_regr_syy", 6); N = transvalues[0]; sumY = transvalues[3]; sumY2 = transvalues[4]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); numerator = N * sumY2 - sumY * sumY; CHECKFLOATVAL(numerator, isinf(sumY2) || isinf(sumY), true); /* Watch out for roundoff error producing a negative numerator */ if (numerator <= 0.0) PG_RETURN_FLOAT8(0.0); PG_RETURN_FLOAT8(numerator / N);}Datumfloat8_regr_sxy(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumY, sumXY, numerator; transvalues = check_float8_array(transarray, "float8_regr_sxy", 6); N = transvalues[0]; sumX = transvalues[1]; sumY = transvalues[3]; sumXY = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); numerator = N * sumXY - sumX * sumY; CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) || isinf(sumY), true); /* A negative result is valid here */ PG_RETURN_FLOAT8(numerator / N);}Datumfloat8_regr_avgx(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX; transvalues = check_float8_array(transarray, "float8_regr_avgx", 6); N = transvalues[0]; sumX = transvalues[1]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); PG_RETURN_FLOAT8(sumX / N);}Datumfloat8_regr_avgy(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumY; transvalues = check_float8_array(transarray, "float8_regr_avgy", 6); N = transvalues[0]; sumY = transvalues[3]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); PG_RETURN_FLOAT8(sumY / N);}Datumfloat8_covar_pop(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumY, sumXY, numerator; transvalues = check_float8_array(transarray, "float8_covar_pop", 6); N = transvalues[0]; sumX = transvalues[1]; sumY = transvalues[3]; sumXY = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); numerator = N * sumXY - sumX * sumY; CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) || isinf(sumY), true); PG_RETURN_FLOAT8(numerator / (N * N));}Datumfloat8_covar_samp(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumY, sumXY, numerator; transvalues = check_float8_array(transarray, "float8_covar_samp", 6); N = transvalues[0]; sumX = transvalues[1]; sumY = transvalues[3]; sumXY = transvalues[5]; /* if N is <= 1 we should return NULL */ if (N < 2.0) PG_RETURN_NULL(); numerator = N * sumXY - sumX * sumY; CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) || isinf(sumY), true); PG_RETURN_FLOAT8(numerator / (N * (N - 1.0)));}Datumfloat8_corr(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumX2, sumY, sumY2, sumXY, numeratorX, numeratorY, numeratorXY; transvalues = check_float8_array(transarray, "float8_corr", 6); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; sumY = transvalues[3]; sumY2 = transvalues[4]; sumXY = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); numeratorX = N * sumX2 - sumX * sumX; CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true); numeratorY = N * sumY2 - sumY * sumY; CHECKFLOATVAL(numeratorY, isinf(sumY2) || isinf(sumY), true); numeratorXY = N * sumXY - sumX * sumY; CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) || isinf(sumY), true); if (numeratorX <= 0 || numeratorY <= 0) PG_RETURN_NULL(); PG_RETURN_FLOAT8(numeratorXY / sqrt(numeratorX * numeratorY));}Datumfloat8_regr_r2(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumX2, sumY, sumY2, sumXY, numeratorX, numeratorY, numeratorXY; transvalues = check_float8_array(transarray, "float8_regr_r2", 6); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; sumY = transvalues[3]; sumY2 = transvalues[4]; sumXY = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); numeratorX = N * sumX2 - sumX * sumX; CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true); numeratorY = N * sumY2 - sumY * sumY; CHECKFLOATVAL(numeratorY, isinf(sumY2) || isinf(sumY), true); numeratorXY = N * sumXY - sumX * sumY; CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) || isinf(sumY), true); if (numeratorX <= 0) PG_RETURN_NULL(); /* per spec, horizontal line produces 1.0 */ if (numeratorY <= 0) PG_RETURN_FLOAT8(1.0); PG_RETURN_FLOAT8((numeratorXY * numeratorXY) / (numeratorX * numeratorY));}Datumfloat8_regr_slope(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumX2, sumY, sumXY, numeratorX, numeratorXY; transvalues = check_float8_array(transarray, "float8_regr_slope", 6); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; sumY = transvalues[3]; sumXY = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); numeratorX = N * sumX2 - sumX * sumX; CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true); numeratorXY = N * sumXY - sumX * sumY; CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) || isinf(sumY), true); if (numeratorX <= 0) PG_RETURN_NULL(); PG_RETURN_FLOAT8(numeratorXY / numeratorX);}Datumfloat8_regr_intercept(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumX2, sumY, sumXY, numeratorX, numeratorXXY; transvalues = check_float8_array(transarray, "float8_regr_intercept", 6); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; sumY = transvalues[3]; sumXY = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); numeratorX = N * sumX2 - sumX * sumX; CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true); numeratorXXY = sumY * sumX2 - sumX * sumXY; CHECKFLOATVAL(numeratorXXY, isinf(sumY) || isinf(sumX2) || isinf(sumX) || isinf(sumXY), true); if (numeratorX <= 0) PG_RETURN_NULL(); PG_RETURN_FLOAT8(numeratorXXY / numeratorX);}/* * ==================================== * MIXED-PRECISION ARITHMETIC OPERATORS * ==================================== *//* * float48pl - returns arg1 + arg2 * float48mi - returns arg1 - arg2 * float48mul - returns arg1 * arg2 * float48div - returns arg1 / arg2 */Datumfloat48pl(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); float8 result; result = arg1 + arg2; CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); PG_RETURN_FLOAT8(result);}Datumfloat48mi(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); float8 result; result = arg1 - arg2; CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); PG_RETURN_FLOAT8(result);}Datumfloat48mul(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); float8 result; result = arg1 * arg2; CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0 || arg2 == 0); PG_RETURN_FLOAT8(result);}Datumfloat48div(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); float8 result; if (arg2 == 0.0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); result = arg1 / arg2; CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0); PG_RETURN_FLOAT8(result);}/* * float84pl - returns arg1 + arg2 * float84mi - returns arg1 - arg2 * float84mul - returns arg1 * arg2 * float84div - returns arg1 / arg2 */Datumfloat84pl(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); float8 result; result = arg1 + arg2; CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); PG_RETURN_FLOAT8(result);}Datumfloat84mi(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); float8 result; result = arg1 - arg2; CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); PG_RETURN_FLOAT8(result);}Datumfloat84mul(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); float8 result; result = arg1 * arg2; CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0 || arg2 == 0); PG_RETURN_FLOAT8(result);}Datumfloat84div(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); float8 result; if (arg2 == 0.0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); result = arg1 / arg2; CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0); PG_RETURN_FLOAT8(result);}/* * ==================== * COMPARISON OPERATORS * ==================== *//* * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations */Datumfloat48eq(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) == 0);}Datumfloat48ne(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) != 0);}Datumfloat48lt(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) < 0);}Datumfloat48le(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) <= 0);}Datumfloat48gt(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) > 0);}Datumfloat48ge(PG_FUNCTION_ARGS){ float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) >= 0);}/* * float84{eq,ne,lt,le,gt,ge} - float8/float4 comparison operations */Datumfloat84eq(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) == 0);}Datumfloat84ne(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) != 0);}Datumfloat84lt(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) < 0);}Datumfloat84le(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) <= 0);}Datumfloat84gt(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) > 0);}Datumfloat84ge(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) >= 0);}/* * Implements the float8 version of the width_bucket() function * defined by SQL2003. See also width_bucket_numeric(). * * 'bound1' and 'bound2' are the lower and upper bounds of the * histogram's range, respectively. 'count' is the number of buckets * in the histogram. width_bucket() returns an integer indicating the * bucket number that 'operand' belongs to in an equiwidth histogram * with the specified characteristics. An operand smaller than the * lower bound is assigned to bucket 0. An operand greater than the * upper bound is assigned to an additional bucket (with number * count+1). We don't allow "NaN" for any of the float8 inputs, and we * don't allow either of the histogram bounds to be +/- infinity. */Datumwidth_bucket_float8(PG_FUNCTION_ARGS){ float8 operand = PG_GETARG_FLOAT8(0); float8 bound1 = PG_GETARG_FLOAT8(1); float8 bound2 = PG_GETARG_FLOAT8(2); int32 count = PG_GETARG_INT32(3); int32 result; if (count <= 0.0) ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION), errmsg("count must be greater than zero"))); if (isnan(operand) || isnan(bound1) || isnan(bound2)) ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION), errmsg("operand, lower bound and upper bound cannot be NaN"))); /* Note that we allow "operand" to be infinite */ if (is_infinite(bound1) || is_infinite(bound2)) ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION), errmsg("lower and upper bounds must be finite"))); if (bound1 < bound2) { if (operand < bound1) result = 0; else if (operand >= bound2) { result = count + 1; /* check for overflow */ if (result < count) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); } else result = ((float8) count * (operand - bound1) / (bound2 - bound1)) + 1; } else if (bound1 > bound2) { if (operand > bound1) result = 0; else if (operand <= bound2) { result = count + 1; /* check for overflow */ if (result < count) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); } else result = ((float8) count * (bound1 - operand) / (bound1 - bound2)) + 1; } else { ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION), errmsg("lower bound cannot equal upper bound"))); result = 0; /* keep the compiler quiet */ } PG_RETURN_INT32(result);}/* ========== PRIVATE ROUTINES ========== */#ifndef HAVE_CBRTstatic doublecbrt(double x){ int isneg = (x < 0.0); double absx = fabs(x); double tmpres = pow(absx, (double) 1.0 / (double) 3.0); /* * The result is somewhat inaccurate --- not really pow()'s fault, as the * exponent it's handed contains roundoff error. We can improve the * accuracy by doing one iteration of Newton's formula. Beware of zero * input however. */ if (tmpres > 0.0) tmpres -= (tmpres - absx / (tmpres * tmpres)) / (double) 3.0; return isneg ? -tmpres : tmpres;}#endif /* !HAVE_CBRT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -