⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 float.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
	errno = 0;	result = exp(arg1);	if (errno == ERANGE && result != 0 && !isinf(result))		result = get_float8_infinity();	CHECKFLOATVAL(result, isinf(arg1), false);	PG_RETURN_FLOAT8(result);}/* *		dlog1			- returns the natural logarithm of arg1 */Datumdlog1(PG_FUNCTION_ARGS){	float8		arg1 = PG_GETARG_FLOAT8(0);	float8		result;	/*	 * Emit particular SQLSTATE error codes for ln(). This is required by the	 * SQL standard.	 */	if (arg1 == 0.0)		ereport(ERROR,				(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),				 errmsg("cannot take logarithm of zero")));	if (arg1 < 0)		ereport(ERROR,				(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),				 errmsg("cannot take logarithm of a negative number")));	result = log(arg1);	CHECKFLOATVAL(result, isinf(arg1), arg1 == 1);	PG_RETURN_FLOAT8(result);}/* *		dlog10			- returns the base 10 logarithm of arg1 */Datumdlog10(PG_FUNCTION_ARGS){	float8		arg1 = PG_GETARG_FLOAT8(0);	float8		result;	/*	 * Emit particular SQLSTATE error codes for log(). The SQL spec doesn't	 * define log(), but it does define ln(), so it makes sense to emit the	 * same error code for an analogous error condition.	 */	if (arg1 == 0.0)		ereport(ERROR,				(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),				 errmsg("cannot take logarithm of zero")));	if (arg1 < 0)		ereport(ERROR,				(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),				 errmsg("cannot take logarithm of a negative number")));	result = log10(arg1);	CHECKFLOATVAL(result, isinf(arg1), arg1 == 1);	PG_RETURN_FLOAT8(result);}/* *		dacos			- returns the arccos of arg1 (radians) */Datumdacos(PG_FUNCTION_ARGS){	float8		arg1 = PG_GETARG_FLOAT8(0);	float8		result;	/*	 * We use errno here because the trigonometric functions are cyclic and	 * hard to check for underflow.	 */	errno = 0;	result = acos(arg1);	if (errno != 0)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("input is out of range")));	CHECKFLOATVAL(result, isinf(arg1), true);	PG_RETURN_FLOAT8(result);}/* *		dasin			- returns the arcsin of arg1 (radians) */Datumdasin(PG_FUNCTION_ARGS){	float8		arg1 = PG_GETARG_FLOAT8(0);	float8		result;	errno = 0;	result = asin(arg1);	if (errno != 0)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("input is out of range")));	CHECKFLOATVAL(result, isinf(arg1), true);	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)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("input is out of range")));	CHECKFLOATVAL(result, isinf(arg1), true);	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)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("input is out of range")));	CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true);	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)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("input is out of range")));	CHECKFLOATVAL(result, isinf(arg1), true);	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)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("input is out of range")));	result = 1.0 / result;	CHECKFLOATVAL(result, true /* cotan(pi/2) == inf */ , true);	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)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("input is out of range")));	CHECKFLOATVAL(result, isinf(arg1), true);	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)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("input is out of range")));	CHECKFLOATVAL(result, true /* tan(pi/2) == Inf */ , true);	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);	CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);	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);	CHECKFLOATVAL(result, isinf(arg1), arg1 == 0);	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 + 1);	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_VOID();}/* *		========================= *		FLOAT AGGREGATE OPERATORS *		========================= * *		float8_accum		- accumulate for AVG(), variance aggregates, etc. *		float4_accum		- same, but input data is float4 *		float8_avg			- produce final result for float AVG() *		float8_var_samp		- produce final result for float VAR_SAMP() *		float8_var_pop		- produce final result for float VAR_POP() *		float8_stddev_samp	- produce final result for float STDDEV_SAMP() *		float8_stddev_pop	- produce final result for float STDDEV_POP() * * 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, int n){	/*	 * We expect the input to be an N-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 N float8 values.	 */	if (ARR_NDIM(transarray) != 1 ||		ARR_DIMS(transarray)[0] != n ||		ARR_HASNULL(transarray) ||		ARR_ELEMTYPE(transarray) != FLOAT8OID)		elog(ERROR, "%s: expected %d-element float8 array", caller, n);	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;	transvalues = check_float8_array(transarray, "float8_accum", 3);	N = transvalues[0];	sumX = transvalues[1];	sumX2 = transvalues[2];	N += 1.0;	sumX += newval;	CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newval), true);	sumX2 += newval * newval;	CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newval), true);	/*	 * If we're invoked by nodeAgg, we can cheat and modify our first	 * parameter in-place to reduce palloc overhead. Otherwise we construct a	 * new array with the updated transition data and return it.	 */	if (fcinfo->context && IsA(fcinfo->context, AggState))	{		transvalues[0] = N;		transvalues[1] = sumX;		transvalues[2] = sumX2;		PG_RETURN_ARRAYTYPE_P(transarray);	}	else	{		Datum		transdatums[3];		ArrayType  *result;		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);	/* do computations as float8 */	float8		newval = PG_GETARG_FLOAT4(1);	float8	   *transvalues;	float8		N,				sumX,				sumX2;	transvalues = check_float8_array(transarray, "float4_accum", 3);	N = transvalues[0];	sumX = transvalues[1];	sumX2 = transvalues[2];	N += 1.0;	sumX += newval;	CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newval), true);	sumX2 += newval * newval;	CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newval), true);	/*	 * If we're invoked by nodeAgg, we can cheat and modify our first	 * parameter in-place to reduce palloc overhead. Otherwise we construct a	 * new array with the updated transition data and return it.	 */	if (fcinfo->context && IsA(fcinfo->context, AggState))	{		transvalues[0] = N;		transvalues[1] = sumX;		transvalues[2] = sumX2;		PG_RETURN_ARRAYTYPE_P(transarray);	}	else	{		Datum		transdatums[3];		ArrayType  *result;		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", 3);	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_var_pop(PG_FUNCTION_ARGS){	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);	float8	   *transvalues;	float8		N,				sumX,				sumX2,				numerator;	transvalues = check_float8_array(transarray, "float8_var_pop", 3);	N = transvalues[0];	sumX = transvalues[1];	sumX2 = transvalues[2];	/* Population variance is undefined when N is 0, so return NULL */	if (N == 0.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 * N));}Datumfloat8_var_samp(PG_FUNCTION_ARGS){	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);	float8	   *transvalues;	float8		N,				sumX,				sumX2,				numerator;	transvalues = check_float8_array(transarray, "float8_var_samp", 3);	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;	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 * (N - 1.0)));}Datumfloat8_stddev_pop(PG_FUNCTION_ARGS){	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);	float8	   *transvalues;	float8		N,				sumX,				sumX2,				numerator;	transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);	N = transvalues[0];	sumX = transvalues[1];	sumX2 = transvalues[2];	/* Population stddev is undefined when N is 0, so return NULL */	if (N == 0.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(sqrt(numerator / (N * N)));}Datumfloat8_stddev_samp(PG_FUNCTION_ARGS){	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);	float8	   *transvalues;	float8		N,				sumX,				sumX2,				numerator;	transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);	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;	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(sqrt(numerator / (N * (N - 1.0))));}/* *		========================= *		SQL2003 BINARY AGGREGATES *		========================= * * The transition datatype for all these aggregates is a 6-element array of * float8, holding the values N, sum(X), sum(X*X), sum(Y), sum(Y*Y), sum(X*Y) * in that order.  Note that Y is the first argument to the aggregates! * * It might seem attractive to optimize this by having multiple accumulator * functions that only calculate the sums actually needed.	But on most * modern machines, a couple of extra floating-point multiplies will be * insignificant compared to the other per-tuple overhead, so I've chosen * to minimize code space instead. */Datumfloat8_regr_accum(PG_FUNCTION_ARGS){	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);	float8		newvalY = PG_GETARG_FLOAT8(1);	float8		newvalX = PG_GETARG_FLOAT8(2);	float8	   *transvalues;	float8		N,				sumX,				sumX2,				sumY,				sumY2,				sumXY;	transvalues = check_float8_array(transarray, "float8_regr_accum", 6);	N = transvalues[0];	sumX = transvalues[1];	sumX2 = transvalues[2];	sumY = transvalues[3];	sumY2 = transvalues[4];	sumXY = transvalues[5];	N += 1.0;	sumX += newvalX;	CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newvalX), true);	sumX2 += newvalX * newvalX;	CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newvalX), true);	sumY += newvalY;	CHECKFLOATVAL(sumY, isinf(transvalues[3]) || isinf(newvalY), true);	sumY2 += newvalY * newvalY;	CHECKFLOATVAL(sumY2, isinf(transvalues[4]) || isinf(newvalY), true);	sumXY += newvalX * newvalY;	CHECKFLOATVAL(sumXY, isinf(transvalues[5]) || isinf(newvalX) ||				  isinf(newvalY), true);	/*	 * If we're invoked by nodeAgg, we can cheat and modify our first	 * parameter in-place to reduce palloc overhead. Otherwise we construct a	 * new array with the updated transition data and return it.	 */	if (fcinfo->context && IsA(fcinfo->context, AggState))	{		transvalues[0] = N;		transvalues[1] = sumX;		transvalues[2] = sumX2;		transvalues[3] = sumY;		transvalues[4] = sumY2;		transvalues[5] = sumXY;		PG_RETURN_ARRAYTYPE_P(transarray);	}	else	{		Datum		transdatums[6];		ArrayType  *result;		transdatums[0] = Float8GetDatumFast(N);		transdatums[1] = Float8GetDatumFast(sumX);		transdatums[2] = Float8GetDatumFast(sumX2);		transdatums[3] = Float8GetDatumFast(sumY);		transdatums[4] = Float8GetDatumFast(sumY2);		transdatums[5] = Float8GetDatumFast(sumXY);		result = construct_array(transdatums, 6,								 FLOAT8OID,								 sizeof(float8),								 false /* float8 byval */ , 'd');		PG_RETURN_ARRAYTYPE_P(result);	}}Datumfloat8_regr_sxx(PG_FUNCTION_ARGS){	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);	float8	   *transvalues;	float8		N,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -