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

📄 numeric.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 5 页
字号:
{	Numeric		res;	NumericVar	arg;	NumericVar	result;	int			res_dscale;	/* ----------	 * Handle NULL	 * ----------	 */	if (num == NULL)		return NULL;	/* ----------	 * Handle NaN	 * ----------	 */	if (NUMERIC_IS_NAN(num))		return make_result(&const_nan);	/* ----------	 * Same procedure like for sqrt().	 * ----------	 */	init_var(&arg);	init_var(&result);	set_var_from_num(num, &arg);	res_dscale = MAX(arg.dscale, NUMERIC_MIN_DISPLAY_SCALE);	res_dscale = MIN(res_dscale, NUMERIC_MAX_DISPLAY_SCALE);	global_rscale = MAX(arg.rscale, NUMERIC_MIN_RESULT_SCALE);	global_rscale = MAX(global_rscale, res_dscale + 4);	global_rscale = MIN(global_rscale, NUMERIC_MAX_RESULT_SCALE);	exp_var(&arg, &result);	result.dscale = res_dscale;	res = make_result(&result);	free_var(&result);	free_var(&arg);	return res;}/* ---------- * numeric_ln() - * *	Compute the natural logarithm of x * ---------- */Numericnumeric_ln(Numeric num){	Numeric		res;	NumericVar	arg;	NumericVar	result;	int			res_dscale;	/* ----------	 * Handle NULL	 * ----------	 */	if (num == NULL)		return NULL;	/* ----------	 * Handle NaN	 * ----------	 */	if (NUMERIC_IS_NAN(num))		return make_result(&const_nan);	/* ----------	 * Same procedure like for sqrt()	 * ----------	 */	init_var(&arg);	init_var(&result);	set_var_from_num(num, &arg);	res_dscale = MAX(arg.dscale, NUMERIC_MIN_DISPLAY_SCALE);	res_dscale = MIN(res_dscale, NUMERIC_MAX_DISPLAY_SCALE);	global_rscale = MAX(arg.rscale, NUMERIC_MIN_RESULT_SCALE);	global_rscale = MAX(global_rscale, res_dscale + 4);	global_rscale = MIN(global_rscale, NUMERIC_MAX_RESULT_SCALE);	ln_var(&arg, &result);	result.dscale = res_dscale;	res = make_result(&result);	free_var(&result);	free_var(&arg);	return res;}/* ---------- * numeric_ln() - * *	Compute the logarithm of x in a given base * ---------- */Numericnumeric_log(Numeric num1, Numeric num2){	Numeric		res;	NumericVar	arg1;	NumericVar	arg2;	NumericVar	result;	int			res_dscale;	/* ----------	 * Handle NULL	 * ----------	 */	if (num1 == NULL || num2 == NULL)		return NULL;	/* ----------	 * Handle NaN	 * ----------	 */	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))		return make_result(&const_nan);	/* ----------	 * Initialize things and calculate scales	 * ----------	 */	init_var(&arg1);	init_var(&arg2);	init_var(&result);	set_var_from_num(num1, &arg1);	set_var_from_num(num2, &arg2);	res_dscale = MAX(arg1.dscale + arg2.dscale, NUMERIC_MIN_DISPLAY_SCALE);	res_dscale = MIN(res_dscale, NUMERIC_MAX_DISPLAY_SCALE);	global_rscale = MAX(arg1.rscale + arg2.rscale, NUMERIC_MIN_RESULT_SCALE);	global_rscale = MAX(global_rscale, res_dscale + 4);	global_rscale = MIN(global_rscale, NUMERIC_MAX_RESULT_SCALE);	/* ----------	 * Call log_var() to compute and return the result	 * ----------	 */	log_var(&arg1, &arg2, &result);	result.dscale = res_dscale;	res = make_result(&result);	free_var(&result);	free_var(&arg2);	free_var(&arg1);	return res;}/* ---------- * numeric_power() - * *	Raise m to the power of x * ---------- */Numericnumeric_power(Numeric num1, Numeric num2){	Numeric		res;	NumericVar	arg1;	NumericVar	arg2;	NumericVar	result;	int			res_dscale;	/* ----------	 * Handle NULL	 * ----------	 */	if (num1 == NULL || num2 == NULL)		return NULL;	/* ----------	 * Handle NaN	 * ----------	 */	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))		return make_result(&const_nan);	/* ----------	 * Initialize things and calculate scales	 * ----------	 */	init_var(&arg1);	init_var(&arg2);	init_var(&result);	set_var_from_num(num1, &arg1);	set_var_from_num(num2, &arg2);	res_dscale = MAX(arg1.dscale + arg2.dscale, NUMERIC_MIN_DISPLAY_SCALE);	res_dscale = MIN(res_dscale, NUMERIC_MAX_DISPLAY_SCALE);	global_rscale = MAX(arg1.rscale + arg2.rscale, NUMERIC_MIN_RESULT_SCALE);	global_rscale = MAX(global_rscale, res_dscale + 4);	global_rscale = MIN(global_rscale, NUMERIC_MAX_RESULT_SCALE);	/* ----------	 * Call log_var() to compute and return the result	 * ----------	 */	power_var(&arg1, &arg2, &result);	result.dscale = res_dscale;	res = make_result(&result);	free_var(&result);	free_var(&arg2);	free_var(&arg1);	return res;}/* ---------------------------------------------------------------------- * * Type conversion functions * * ---------------------------------------------------------------------- */Numericint4_numeric(int32 val){	Numeric		res;	NumericVar	result;	char	   *tmp;	init_var(&result);	tmp = int4out(val);	set_var_from_str(tmp, &result);	res = make_result(&result);	free_var(&result);	pfree(tmp);	return res;}int32numeric_int4(Numeric num){	char	   *tmp;	int32		result;	if (num == NULL)		return 0;	if (NUMERIC_IS_NAN(num))		return 0;	tmp = numeric_out(num);	result = int4in(tmp);	pfree(tmp);	return result;}Numericfloat8_numeric(float64 val){	Numeric		res;	NumericVar	result;	char		buf[512];	if (val == NULL)		return NULL;	if (isnan(*val))		return make_result(&const_nan);	init_var(&result);	sprintf(buf, "%f", *val);	set_var_from_str(buf, &result);	res = make_result(&result);	free_var(&result);	return res;}float64numeric_float8(Numeric num){	char	   *tmp;	float64		result;	if (num == NULL)		return NULL;	if (NUMERIC_IS_NAN(num))	{		result = (float64) palloc(sizeof(float64data));		*result = NAN;		return result;	}	tmp = numeric_out(num);	result = float8in(tmp);	pfree(tmp);	return result;}Numericfloat4_numeric(float32 val){	Numeric		res;	NumericVar	result;	char	   *tmp;	if (val == NULL)		return NULL;	if (isnan(*val))		return make_result(&const_nan);	init_var(&result);	tmp = float4out(val);	set_var_from_str(tmp, &result);	res = make_result(&result);	free_var(&result);	pfree(tmp);	return res;}float32numeric_float4(Numeric num){	char	   *tmp;	float32		result;	if (num == NULL)		return NULL;	if (NUMERIC_IS_NAN(num))	{		result = (float32) palloc(sizeof(float32data));		*result = NAN;		return result;	}	tmp = numeric_out(num);	result = float4in(tmp);	pfree(tmp);	return result;}/* ---------------------------------------------------------------------- * * Local functions follow * * ---------------------------------------------------------------------- */#ifdef NUMERIC_DEBUG/* ---------- * dump_numeric() - Dump a value in the db storage format for debugging * ---------- */static voiddump_numeric(char *str, Numeric num){	int			i;	printf("%s: NUMERIC w=%d r=%d d=%d ", str, num->n_weight, num->n_rscale,		   NUMERIC_DSCALE(num));	switch (NUMERIC_SIGN(num))	{		case NUMERIC_POS:			printf("POS");			break;		case NUMERIC_NEG:			printf("NEG");			break;		case NUMERIC_NAN:			printf("NaN");			break;		default:			printf("SIGN=0x%x", NUMERIC_SIGN(num));			break;	}	for (i = 0; i < num->varlen - NUMERIC_HDRSZ; i++)		printf(" %d %d", (num->n_data[i] >> 4) & 0x0f, num->n_data[i] & 0x0f);	printf("\n");}/* ---------- * dump_var() - Dump a value in the variable format for debugging * ---------- */static voiddump_var(char *str, NumericVar *var){	int			i;	printf("%s: VAR w=%d r=%d d=%d ", str, var->weight, var->rscale,		   var->dscale);	switch (var->sign)	{		case NUMERIC_POS:			printf("POS");			break;		case NUMERIC_NEG:			printf("NEG");			break;		case NUMERIC_NAN:			printf("NaN");			break;		default:			printf("SIGN=0x%x", var->sign);			break;	}	for (i = 0; i < var->ndigits; i++)		printf(" %d", var->digits[i]);	printf("\n");}#endif	 /* NUMERIC_DEBUG *//* ---------- * digitbuf_alloc() - * *	All variables used in the arithmetic functions hold some base *	information (sign, scales etc.) and a digit buffer for the *	value itself. All the variable level functions are written in *	a style that makes it possible to give one and the same variable *	as argument and result destination. * *	The two functions below manage unused buffers in a free list *	as a try to reduce the number of malloc()/free() calls. * ---------- */static NumericDigitBuf *digitbuf_alloc(int size){	NumericDigitBuf *buf;	int			asize;	/* ----------	 * Lookup the free list if there is a digit buffer of	 * the required size available	 * ----------	 */	for (buf = digitbuf_freelist; buf != NULL; buf = buf->next)	{		if (buf->size < size)			continue;		/* ----------		 * We found a free buffer that is big enough - remove it from		 * the free list		 * ----------		 */		if (buf->prev == NULL)		{			digitbuf_freelist = buf->next;			if (buf->next != NULL)				buf->next->prev = NULL;		}		else		{			buf->prev->next = buf->next;			if (buf->next != NULL)				buf->next->prev = buf->prev;		}		digitbuf_nfree--;		/* ----------		 * Put it onto the used list		 * ----------		 */		buf->prev = NULL;		buf->next = digitbuf_usedlist;		if (digitbuf_usedlist != NULL)			digitbuf_usedlist->prev = buf;		digitbuf_usedlist = buf;		/* ----------		 * Return this buffer		 * ----------		 */		return buf;	}	/* ----------	 * There is no free buffer big enough - allocate a new one	 * ----------	 */	for (asize = NUMERIC_MIN_BUFSIZE; asize < size; asize *= 2);	buf = (NumericDigitBuf *) malloc(sizeof(NumericDigitBuf) + asize);	buf->size = asize;	/* ----------	 * Put it onto the used list	 * ----------	 */	buf->prev = NULL;	buf->next = digitbuf_usedlist;	if (digitbuf_usedlist != NULL)		digitbuf_usedlist->prev = buf;	digitbuf_usedlist = buf;	/* ----------	 * Return the new buffer	 * ----------	 */	return buf;}/* ---------- * digitbuf_free() - * ---------- */static voiddigitbuf_free(NumericDigitBuf *buf){	NumericDigitBuf *smallest;	if (buf == NULL)		return;	/* ----------	 * Remove the buffer from the used list	 * ----------	 */	if (buf->prev == NULL)	{		digitbuf_usedlist = buf->next;		if (buf->next != NULL)			buf->next->prev = NULL;	}	else	{		buf->prev->next = buf->next;		if (buf->next != NULL)			buf->next->prev = buf->prev;	}	/* ----------	 * Put it onto the free list	 * ----------	 */	if (digitbuf_freelist != NULL)		digitbuf_freelist->prev = buf;	buf->prev = NULL;	buf->next = digitbuf_freelist;	digitbuf_freelist = buf;	digitbuf_nfree++;	/* ----------	 * Check for maximum free buffers	 * ----------	 */	if (digitbuf_nfree <= NUMERIC_MAX_FREEBUFS)		return;	/* ----------	 * Have too many free buffers - destroy the smallest one	 * ----------	 */	smallest = buf;	for (buf = digitbuf_freelist->next; buf != NULL; buf = buf->next)	{		if (buf->size < smallest->size)			smallest = buf;	}	/* ----------	 * Remove it from the free list	 * ----------	 */	if (smallest->prev == NULL)	{		digitbuf_freelist = smallest->next;		if (smallest->next != NULL)			smallest->next->prev = NULL;	}	else	{		smallest->prev->next = smallest->next;		if (smallest->next != NULL)			smallest->next->prev = smallest->prev;	}	digitbuf_nfree--;	/* ----------	 * And destroy it	 * ----------	 */	free(smallest);}/* ---------- * free_var() - * *	Return the digit buffer of a variable to the pool * ---------- */static voidfree_var(NumericVar *var){	if (var->buf != NULL)	{		digitbuf_free(var->buf);		var->buf = NULL;		var->digits = NULL;	}	var->sign = NUMERIC_NAN;}/* ---------- * free_allvars() - * *	Put all the currently used buffers back into the pool. * *	Warning: the variables currently holding the buffers aren't *	cleaned! This function should only be used directly before *	a call to elog(ERROR,...) or if it is totally impossible that *	any other call to free_var() will occur. None of the variable *	level functions should call it if it might return later without *	an error. * ---------- */static voidfree_allvars(void){	NumericDigitBuf *buf;	NumericDigitBuf *next;	buf = digitbuf_usedlist;	while (buf != NULL)	{		next = buf->next;		digitbuf_free(buf);		buf = next;	}}/* ---------- * set_var_from_str() * *	Parse a string and put the number into a variable * ---------- */static voidset_var_from_str(char *str, NumericVar *dest){	char	   *cp = str;	bool		have_dp = FALSE;	int			i = 1;	while (*cp)	{		if (!isspace(*cp))			break;		cp++;	}	digitbuf_free(dest->buf);	dest->buf = digitbuf_alloc(strlen(cp) + 2);	dest->digits = (NumericDigit *) (dest->buf) + sizeof(NumericDigitBuf);	dest->digits[0] = 0;	dest->weight = 0;	dest->dscale = 0;	switch (*cp)

⌨️ 快捷键说明

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