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

📄 numeric.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 5 页
字号:
	free_var(&result);	free_var(&arg2);	free_var(&arg1);	PG_RETURN_NUMERIC(res);}/* * numeric_inc() - * *	Increment a number by one */Datumnumeric_inc(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	NumericVar	arg;	Numeric		res;	/*	 * Handle NaN	 */	if (NUMERIC_IS_NAN(num))		PG_RETURN_NUMERIC(make_result(&const_nan));	/*	 * Compute the result and return it	 */	init_var(&arg);	set_var_from_num(num, &arg);	add_var(&arg, &const_one, &arg);	res = make_result(&arg);	free_var(&arg);	PG_RETURN_NUMERIC(res);}/* * numeric_smaller() - * *	Return the smaller of two numbers */Datumnumeric_smaller(PG_FUNCTION_ARGS){	Numeric		num1 = PG_GETARG_NUMERIC(0);	Numeric		num2 = PG_GETARG_NUMERIC(1);	/*	 * Use cmp_numerics so that this will agree with the comparison	 * operators, particularly as regards comparisons involving NaN.	 */	if (cmp_numerics(num1, num2) < 0)		PG_RETURN_NUMERIC(num1);	else		PG_RETURN_NUMERIC(num2);}/* * numeric_larger() - * *	Return the larger of two numbers */Datumnumeric_larger(PG_FUNCTION_ARGS){	Numeric		num1 = PG_GETARG_NUMERIC(0);	Numeric		num2 = PG_GETARG_NUMERIC(1);	/*	 * Use cmp_numerics so that this will agree with the comparison	 * operators, particularly as regards comparisons involving NaN.	 */	if (cmp_numerics(num1, num2) > 0)		PG_RETURN_NUMERIC(num1);	else		PG_RETURN_NUMERIC(num2);}/* ---------------------------------------------------------------------- * * Advanced math functions * * ---------------------------------------------------------------------- *//* * numeric_sqrt() - * *	Compute the square root of a numeric. */Datumnumeric_sqrt(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	Numeric		res;	NumericVar	arg;	NumericVar	result;	int			sweight;	int			rscale;	/*	 * Handle NaN	 */	if (NUMERIC_IS_NAN(num))		PG_RETURN_NUMERIC(make_result(&const_nan));	/*	 * Unpack the argument and determine the result scale.	We choose a	 * scale to give at least NUMERIC_MIN_SIG_DIGITS significant digits;	 * but in any case not less than the input's dscale.	 */	init_var(&arg);	init_var(&result);	set_var_from_num(num, &arg);	/* Assume the input was normalized, so arg.weight is accurate */	sweight = (arg.weight + 1) * DEC_DIGITS / 2 - 1;	rscale = NUMERIC_MIN_SIG_DIGITS - sweight;	rscale = Max(rscale, arg.dscale);	rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);	rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);	/*	 * Let sqrt_var() do the calculation and return the result.	 */	sqrt_var(&arg, &result, rscale);	res = make_result(&result);	free_var(&result);	free_var(&arg);	PG_RETURN_NUMERIC(res);}/* * numeric_exp() - * *	Raise e to the power of x */Datumnumeric_exp(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	Numeric		res;	NumericVar	arg;	NumericVar	result;	int			rscale;	double		val;	/*	 * Handle NaN	 */	if (NUMERIC_IS_NAN(num))		PG_RETURN_NUMERIC(make_result(&const_nan));	/*	 * Unpack the argument and determine the result scale.	We choose a	 * scale to give at least NUMERIC_MIN_SIG_DIGITS significant digits;	 * but in any case not less than the input's dscale.	 */	init_var(&arg);	init_var(&result);	set_var_from_num(num, &arg);	/* convert input to float8, ignoring overflow */	val = numericvar_to_double_no_overflow(&arg);	/*	 * log10(result) = num * log10(e), so this is approximately the	 * decimal weight of the result:	 */	val *= 0.434294481903252;	/* limit to something that won't cause integer overflow */	val = Max(val, -NUMERIC_MAX_RESULT_SCALE);	val = Min(val, NUMERIC_MAX_RESULT_SCALE);	rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;	rscale = Max(rscale, arg.dscale);	rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);	rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);	/*	 * Let exp_var() do the calculation and return the result.	 */	exp_var(&arg, &result, rscale);	res = make_result(&result);	free_var(&result);	free_var(&arg);	PG_RETURN_NUMERIC(res);}/* * numeric_ln() - * *	Compute the natural logarithm of x */Datumnumeric_ln(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	Numeric		res;	NumericVar	arg;	NumericVar	result;	int			dec_digits;	int			rscale;	/*	 * Handle NaN	 */	if (NUMERIC_IS_NAN(num))		PG_RETURN_NUMERIC(make_result(&const_nan));	init_var(&arg);	init_var(&result);	set_var_from_num(num, &arg);	/* Approx decimal digits before decimal point */	dec_digits = (arg.weight + 1) * DEC_DIGITS;	if (dec_digits > 1)		rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(dec_digits - 1);	else if (dec_digits < 1)		rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(1 - dec_digits);	else		rscale = NUMERIC_MIN_SIG_DIGITS;	rscale = Max(rscale, arg.dscale);	rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);	rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);	ln_var(&arg, &result, rscale);	res = make_result(&result);	free_var(&result);	free_var(&arg);	PG_RETURN_NUMERIC(res);}/* * numeric_log() - * *	Compute the logarithm of x in a given base */Datumnumeric_log(PG_FUNCTION_ARGS){	Numeric		num1 = PG_GETARG_NUMERIC(0);	Numeric		num2 = PG_GETARG_NUMERIC(1);	Numeric		res;	NumericVar	arg1;	NumericVar	arg2;	NumericVar	result;	/*	 * Handle NaN	 */	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))		PG_RETURN_NUMERIC(make_result(&const_nan));	/*	 * Initialize things	 */	init_var(&arg1);	init_var(&arg2);	init_var(&result);	set_var_from_num(num1, &arg1);	set_var_from_num(num2, &arg2);	/*	 * Call log_var() to compute and return the result; note it handles	 * scale selection itself.	 */	log_var(&arg1, &arg2, &result);	res = make_result(&result);	free_var(&result);	free_var(&arg2);	free_var(&arg1);	PG_RETURN_NUMERIC(res);}/* * numeric_power() - * *	Raise b to the power of x */Datumnumeric_power(PG_FUNCTION_ARGS){	Numeric		num1 = PG_GETARG_NUMERIC(0);	Numeric		num2 = PG_GETARG_NUMERIC(1);	Numeric		res;	NumericVar	arg1;	NumericVar	arg2;	NumericVar	result;	/*	 * Handle NaN	 */	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))		PG_RETURN_NUMERIC(make_result(&const_nan));	/*	 * Initialize things	 */	init_var(&arg1);	init_var(&arg2);	init_var(&result);	set_var_from_num(num1, &arg1);	set_var_from_num(num2, &arg2);	/*	 * Call power_var() to compute and return the result; note it handles	 * scale selection itself.	 */	power_var(&arg1, &arg2, &result);	res = make_result(&result);	free_var(&result);	free_var(&arg2);	free_var(&arg1);	PG_RETURN_NUMERIC(res);}/* ---------------------------------------------------------------------- * * Type conversion functions * * ---------------------------------------------------------------------- */Datumint4_numeric(PG_FUNCTION_ARGS){	int32		val = PG_GETARG_INT32(0);	Numeric		res;	NumericVar	result;	init_var(&result);	int8_to_numericvar((int64) val, &result);	res = make_result(&result);	free_var(&result);	PG_RETURN_NUMERIC(res);}Datumnumeric_int4(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	NumericVar	x;	int64		val;	int32		result;	/* XXX would it be better to return NULL? */	if (NUMERIC_IS_NAN(num))		ereport(ERROR,				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),				 errmsg("cannot convert NaN to integer")));	/* Convert to variable format and thence to int8 */	init_var(&x);	set_var_from_num(num, &x);	if (!numericvar_to_int8(&x, &val))		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));	free_var(&x);	/* Down-convert to int4 */	result = (int32) val;	/* Test for overflow by reverse-conversion. */	if ((int64) result != val)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));	PG_RETURN_INT32(result);}Datumint8_numeric(PG_FUNCTION_ARGS){	int64		val = PG_GETARG_INT64(0);	Numeric		res;	NumericVar	result;	init_var(&result);	int8_to_numericvar(val, &result);	res = make_result(&result);	free_var(&result);	PG_RETURN_NUMERIC(res);}Datumnumeric_int8(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	NumericVar	x;	int64		result;	/* XXX would it be better to return NULL? */	if (NUMERIC_IS_NAN(num))		ereport(ERROR,				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),				 errmsg("cannot convert NaN to integer")));	/* Convert to variable format and thence to int8 */	init_var(&x);	set_var_from_num(num, &x);	if (!numericvar_to_int8(&x, &result))		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));	free_var(&x);	PG_RETURN_INT64(result);}Datumint2_numeric(PG_FUNCTION_ARGS){	int16		val = PG_GETARG_INT16(0);	Numeric		res;	NumericVar	result;	init_var(&result);	int8_to_numericvar((int64) val, &result);	res = make_result(&result);	free_var(&result);	PG_RETURN_NUMERIC(res);}Datumnumeric_int2(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	NumericVar	x;	int64		val;	int16		result;	/* XXX would it be better to return NULL? */	if (NUMERIC_IS_NAN(num))		ereport(ERROR,				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),				 errmsg("cannot convert NaN to integer")));	/* Convert to variable format and thence to int8 */	init_var(&x);	set_var_from_num(num, &x);	if (!numericvar_to_int8(&x, &val))		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));	free_var(&x);	/* Down-convert to int2 */	result = (int16) val;	/* Test for overflow by reverse-conversion. */	if ((int64) result != val)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));	PG_RETURN_INT16(result);}Datumfloat8_numeric(PG_FUNCTION_ARGS){	float8		val = PG_GETARG_FLOAT8(0);	Numeric		res;	NumericVar	result;	char		buf[DBL_DIG + 100];	if (isnan(val))		PG_RETURN_NUMERIC(make_result(&const_nan));	sprintf(buf, "%.*g", DBL_DIG, val);	init_var(&result);	set_var_from_str(buf, &result);	res = make_result(&result);	free_var(&result);	PG_RETURN_NUMERIC(res);}Datumnumeric_float8(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	char	   *tmp;	Datum		result;	if (NUMERIC_IS_NAN(num))		PG_RETURN_FLOAT8(NAN);	tmp = DatumGetCString(DirectFunctionCall1(numeric_out,											  NumericGetDatum(num)));	result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));	pfree(tmp);	PG_RETURN_DATUM(result);}/* Convert numeric to float8; if out of range, return +/- HUGE_VAL */Datumnumeric_float8_no_overflow(PG_FUNCTION_ARGS){	Numeric		num = PG_GETARG_NUMERIC(0);	double		val;	if (NUMERIC_IS_NAN(num))		PG_RETURN_FLOAT8(NAN);	val = numeric_to_double_no_overflow(num);	PG_RETURN_FLOAT8(val);}Datumfloat4_numeric(PG_FUNCTION_ARGS){	float4		val = PG_GETARG_FLOAT4(0);	Numeric		res;	NumericVar	result;	char		buf[FLT_DIG + 100];	if (isnan(val))		PG_RETURN_NUMERIC(make_result(&const_nan));	sprintf(buf, "%.*g", FLT_DIG, val);

⌨️ 快捷键说明

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