📄 float.c
字号:
float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; errno = 0; result = asin(arg1); if (errno != 0#ifdef HAVE_FINITE || !finite(result)#endif ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * datan - returns the arctan of arg1 (radians) */Datumdatan(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; errno = 0; result = atan(arg1); if (errno != 0#ifdef HAVE_FINITE || !finite(result)#endif ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * atan2 - returns the arctan2 of arg1 (radians) */Datumdatan2(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); float8 result; errno = 0; result = atan2(arg1, arg2); if (errno != 0#ifdef HAVE_FINITE || !finite(result)#endif ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * dcos - returns the cosine of arg1 (radians) */Datumdcos(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; errno = 0; result = cos(arg1); if (errno != 0#ifdef HAVE_FINITE || !finite(result)#endif ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * dcot - returns the cotangent of arg1 (radians) */Datumdcot(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; errno = 0; result = tan(arg1); if (errno != 0 || result == 0.0#ifdef HAVE_FINITE || !finite(result)#endif ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); result = 1.0 / result; CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * dsin - returns the sine of arg1 (radians) */Datumdsin(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; errno = 0; result = sin(arg1); if (errno != 0#ifdef HAVE_FINITE || !finite(result)#endif ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * dtan - returns the tangent of arg1 (radians) */Datumdtan(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; errno = 0; result = tan(arg1); if (errno != 0#ifdef HAVE_FINITE || !finite(result)#endif ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * degrees - returns degrees converted from radians */Datumdegrees(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; result = arg1 * (180.0 / M_PI); CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * dpi - returns the constant PI */Datumdpi(PG_FUNCTION_ARGS){ PG_RETURN_FLOAT8(M_PI);}/* * radians - returns radians converted from degrees */Datumradians(PG_FUNCTION_ARGS){ float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; result = arg1 * (M_PI / 180.0); CheckFloat8Val(result); PG_RETURN_FLOAT8(result);}/* * drandom - returns a random number */Datumdrandom(PG_FUNCTION_ARGS){ float8 result; /* result 0.0-1.0 */ result = ((double) random()) / ((double) MAX_RANDOM_VALUE); PG_RETURN_FLOAT8(result);}/* * setseed - set seed for the random number generator */Datumsetseed(PG_FUNCTION_ARGS){ float8 seed = PG_GETARG_FLOAT8(0); int iseed = (int) (seed * MAX_RANDOM_VALUE); srandom((unsigned int) iseed); PG_RETURN_INT32(iseed);}/* * ========================= * FLOAT AGGREGATE OPERATORS * ========================= * * float8_accum - accumulate for AVG(), STDDEV(), etc * float4_accum - same, but input data is float4 * float8_avg - produce final result for float AVG() * float8_variance - produce final result for float VARIANCE() * float8_stddev - produce final result for float STDDEV() * * The transition datatype for all these aggregates is a 3-element array * of float8, holding the values N, sum(X), sum(X*X) in that order. * * Note that we represent N as a float to avoid having to build a special * datatype. Given a reasonable floating-point implementation, there should * be no accuracy loss unless N exceeds 2 ^ 52 or so (by which time the * user will have doubtless lost interest anyway...) */static float8 *check_float8_array(ArrayType *transarray, const char *caller){ /* * We expect the input to be a 3-element float array; verify that. We * don't need to use deconstruct_array() since the array data is just * going to look like a C array of 3 float8 values. */ if (ARR_NDIM(transarray) != 1 || ARR_DIMS(transarray)[0] != 3 || ARR_ELEMTYPE(transarray) != FLOAT8OID) elog(ERROR, "%s: expected 3-element float8 array", caller); return (float8 *) ARR_DATA_PTR(transarray);}Datumfloat8_accum(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 newval = PG_GETARG_FLOAT8(1); float8 *transvalues; float8 N, sumX, sumX2; Datum transdatums[3]; ArrayType *result; transvalues = check_float8_array(transarray, "float8_accum"); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; N += 1.0; sumX += newval; sumX2 += newval * newval; transdatums[0] = Float8GetDatumFast(N); transdatums[1] = Float8GetDatumFast(sumX); transdatums[2] = Float8GetDatumFast(sumX2); result = construct_array(transdatums, 3, FLOAT8OID, sizeof(float8), false /* float8 byval */ , 'd'); PG_RETURN_ARRAYTYPE_P(result);}Datumfloat4_accum(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float4 newval4 = PG_GETARG_FLOAT4(1); float8 *transvalues; float8 N, sumX, sumX2, newval; Datum transdatums[3]; ArrayType *result; transvalues = check_float8_array(transarray, "float4_accum"); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; /* Do arithmetic in float8 for best accuracy */ newval = newval4; N += 1.0; sumX += newval; sumX2 += newval * newval; transdatums[0] = Float8GetDatumFast(N); transdatums[1] = Float8GetDatumFast(sumX); transdatums[2] = Float8GetDatumFast(sumX2); result = construct_array(transdatums, 3, FLOAT8OID, sizeof(float8), false /* float8 byval */ , 'd'); PG_RETURN_ARRAYTYPE_P(result);}Datumfloat8_avg(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX; transvalues = check_float8_array(transarray, "float8_avg"); N = transvalues[0]; sumX = transvalues[1]; /* ignore sumX2 */ /* SQL92 defines AVG of no values to be NULL */ if (N == 0.0) PG_RETURN_NULL(); PG_RETURN_FLOAT8(sumX / N);}Datumfloat8_variance(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumX2, numerator; transvalues = check_float8_array(transarray, "float8_variance"); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; /* Sample variance is undefined when N is 0 or 1, so return NULL */ if (N <= 1.0) PG_RETURN_NULL(); numerator = N * sumX2 - sumX * sumX; /* Watch out for roundoff error producing a negative numerator */ if (numerator <= 0.0) PG_RETURN_FLOAT8(0.0); PG_RETURN_FLOAT8(numerator / (N * (N - 1.0)));}Datumfloat8_stddev(PG_FUNCTION_ARGS){ ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, sumX, sumX2, numerator; transvalues = check_float8_array(transarray, "float8_stddev"); N = transvalues[0]; sumX = transvalues[1]; sumX2 = transvalues[2]; /* Sample stddev is undefined when N is 0 or 1, so return NULL */ if (N <= 1.0) PG_RETURN_NULL(); numerator = N * sumX2 - sumX * sumX; /* Watch out for roundoff error producing a negative numerator */ if (numerator <= 0.0) PG_RETURN_FLOAT8(0.0); PG_RETURN_FLOAT8(sqrt(numerator / (N * (N - 1.0))));}/* * ==================================== * 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; CheckFloat8Val(result); 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; CheckFloat8Val(result); 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; CheckFloat8Val(result); 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; CheckFloat8Val(result); 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; CheckFloat8Val(result); 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; CheckFloat8Val(result); 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; CheckFloat8Val(result); 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; CheckFloat8Val(result); 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);}/* ========== PRIVATE ROUTINES ========== */#ifndef HAVE_CBRTstatic doublecbrt(double x){ int isneg = (x < 0.0); double tmpres = pow(fabs(x), (double) 1.0 / (double) 3.0); return isneg ? -tmpres : tmpres;}#endif /* !HAVE_CBRT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -