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

📄 numutils.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * numutils.c *	  utility functions for I/O of built-in numeric types. * *		integer:				itoa, ltoa *		floating point:			ftoa, atof1 * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/numutils.c,v 1.34.2.1 1999/08/02 05:24:56 scrappy Exp $ * *------------------------------------------------------------------------- */#include <errno.h>#include <math.h>#include "postgres.h"#ifdef HAVE_LIMITS_H#include <limits.h>#endif#include "utils/builtins.h"#ifndef INT_MAX#define INT_MAX (0x7FFFFFFFL)#endif#ifndef INT_MIN#define INT_MIN (-INT_MAX-1)#endif#ifndef SHRT_MAX#define SHRT_MAX (0x7FFF)#endif#ifndef SHRT_MIN#define SHRT_MIN (-SHRT_MAX-1)#endif#ifndef SCHAR_MAX#define SCHAR_MAX (0x7F)#endif#ifndef SCHAR_MIN#define SCHAR_MIN (-SCHAR_MAX-1)#endifint32pg_atoi(char *s, int size, int c){	long		l = 0;	char	   *badp = (char *) NULL;	Assert(s);	errno = 0;	/*	 * Some versions of strtol treat the empty string as an error.	This	 * code will explicitly return 0 for an empty string.	 */	if (s == (char *) NULL)		elog(ERROR, "pg_atoi: NULL pointer!");	else if (*s == 0)		l = (long) 0;	else		l = strtol(s, &badp, 10);	if (errno)					/* strtol must set ERANGE */		elog(ERROR, "pg_atoi: error reading \"%s\": %m", s);	if (badp && *badp && (*badp != c))		elog(ERROR, "pg_atoi: error in \"%s\": can\'t parse \"%s\"", s, badp);	switch (size)	{		case sizeof(int32):#if defined(HAVE_LONG_INT_64)			/* won't get ERANGE on these with 64-bit longs... */			if (l < INT_MIN)			{				errno = ERANGE;				elog(ERROR, "pg_atoi: error reading \"%s\": %m", s);			}			if (l > INT_MAX)			{				errno = ERANGE;				elog(ERROR, "pg_atoi: error reading \"%s\": %m", s);			}#endif         /* HAVE_LONG_INT_64 */			break;		case sizeof(int16):			if (l < SHRT_MIN)			{				errno = ERANGE;				elog(ERROR, "pg_atoi: error reading \"%s\": %m", s);			}			if (l > SHRT_MAX)			{				errno = ERANGE;				elog(ERROR, "pg_atoi: error reading \"%s\": %m", s);			}			break;		case sizeof(int8):			if (l < SCHAR_MIN)			{				errno = ERANGE;				elog(ERROR, "pg_atoi: error reading \"%s\": %m", s);			}			if (l > SCHAR_MAX)			{				errno = ERANGE;				elog(ERROR, "pg_atoi: error reading \"%s\": %m", s);			}			break;		default:			elog(ERROR, "pg_atoi: invalid result size: %d", size);	}	return (int32) l;}/* *		itoa			- converts a short int to its string represention * *		Note: *				previously based on ~ingres/source/gutil/atoi.c *				now uses vendor's sprintf conversion */voiditoa(int i, char *a){	sprintf(a, "%hd", (short) i);}/* *		ltoa			- converts a long int to its string represention * *		Note: *				previously based on ~ingres/source/gutil/atoi.c *				now uses vendor's sprintf conversion */voidltoa(int32 l, char *a){	sprintf(a, "%d", l);}/* **  ftoa		- FLOATING POINT TO ASCII CONVERSION ** **		CODE derived from ingres, ~ingres/source/gutil/ftoa.c ** **		'Value' is converted to an ascii character string and stored **		into 'ascii'.  Ascii should have room for at least 'width' + 1 **		characters.  'Width' is the width of the output field (max). **		'Prec' is the number of characters to put after the decimal **		point.	The format of the output string is controlled by **		'format'. ** **		'Format' can be: **				e or E: "E" format output **				f or F:  "F" format output **				g or G:  "F" format output if it will fit, otherwise **						use "E" format. **				n or N:  same as G, but decimal points will not always **						be aligned. ** **		If 'format' is upper case, the "E" comes out in upper case; **		otherwise it comes out in lower case. ** **		When the field width is not big enough, it fills the field with **		stars ("*****") and returns zero.  Normal return is the width **		of the output field (sometimes shorter than 'width'). */#ifdef NOT_USEDintftoa(double value, char *ascii, int width, int prec1, char format){#ifndef HAVE_FCVT	char		out[256];	char		fmt[256];	int			ret;	sprintf(fmt, "%%%d.%d%c", width, prec1, format);	sprintf(out, fmt, value);	if ((ret = strlen(out)) > width)	{		MemSet(ascii, '*', width - 2);		ascii[width] = 0;		return 0;	}	strcpy(ascii, out);	return ret;#else	auto int	expon;	auto int	sign;	int			avail = 0;	char	   *a = NULL;	char	   *p = NULL;	char		mode;	int			lowercase;	int			prec;/*	  extern char		*ecvt(), *fcvt();*/	prec = prec1;	mode = format;	lowercase = 'a' - 'A';	if (mode >= 'a')		mode -= 'a' - 'A';	else		lowercase = 0;	if (mode != 'E')	{		/* try 'F' style output */		p = fcvt(value, prec, &expon, &sign);		avail = width;		a = ascii;		/* output sign */		if (sign)		{			avail--;			*a++ = '-';		}		/* output '0' before the decimal point */		if (expon <= 0)		{			*a++ = '0';			avail--;		}		/* compute space length left after dec pt and fraction */		avail -= prec + 1;		if (mode == 'G')			avail -= 4;		if (avail >= expon)		{			/* it fits.  output */			while (expon > 0)			{				/* output left of dp */				expon--;				if (*p)					*a++ = *p++;				else					*a++ = '0';			}			/* output fraction (right of dec pt) */			avail = expon;			goto frac_out;		}		/* won't fit; let's hope for G format */	}	if (mode != 'F')	{		/* try to do E style output */		p = ecvt(value, prec + 1, &expon, &sign);		avail = width - 5;		a = ascii;		/* output the sign */		if (sign)		{			*a++ = '-';			avail--;		}	}	/* check for field too small */	if (mode == 'F' || avail < prec)	{		/* sorry joker, you lose */		a = ascii;		for (avail = width; avail > 0; avail--)			*a++ = '*';		*a = 0;		return 0;	}	/* it fits; output the number */	mode = 'E';	/* output the LHS single digit */	*a++ = *p++;	expon--;	/* output the rhs */	avail = 1;frac_out:	*a++ = '.';	while (prec > 0)	{		prec--;		if (avail < 0)		{			avail++;			*a++ = '0';		}		else		{			if (*p)				*a++ = *p++;			else				*a++ = '0';		}	}	/* output the exponent */	if (mode == 'E')	{		*a++ = 'E' + lowercase;		if (expon < 0)		{			*a++ = '-';			expon = -expon;		}		else			*a++ = '+';		*a++ = (expon / 10) % 10 + '0';		*a++ = expon % 10 + '0';	}	/* output spaces on the end in G format */	if (mode == 'G')	{		*a++ = ' ';		*a++ = ' ';		*a++ = ' ';		*a++ = ' ';	}	/* finally, we can return */	*a = 0;	avail = a - ascii;	return avail;#endif}#endif/* **   atof1		- ASCII TO FLOATING CONVERSION ** **		CODE derived from ~ingres/source/gutil/atof.c ** **		Converts the string 'str' to floating point and stores the **		result into the cell pointed to by 'val'. ** **		The syntax which it accepts is pretty much what you would **		expect.  Basically, it is: **				{<sp>} [+|-] {<sp>} {<digit>} [.{digit}] {<sp>} [<exp>] **		where <exp> is "e" or "E" followed by an integer, <sp> is a **		space character, <digit> is zero through nine, [] is zero or **		one, and {} is zero or more. ** **		Parameters: **				str -- string to convert. **				val -- pointer to place to put the result (which **						must be type double). ** **		Returns: **				zero -- ok. **				-1 -- syntax error. **				+1 -- overflow (not implemented). ** **		Side Effects: **				clobbers *val. */#ifdef NOT_USEDintatof1(char *str, double *val){	char	   *p;	double		v;	double		fact;	int			minus;	char		c;	int			expon;	int			gotmant;	v = 0.0;	p = str;	minus = 0;	/* skip leading blanks */	while ((c = *p) != '\0')	{		if (c != ' ')			break;		p++;	}	/* handle possible sign */	switch (c)	{		case '-':			minus++;		case '+':			p++;	}	/* skip blanks after sign */	while ((c = *p) != '\0')	{		if (c != ' ')			break;		p++;	}	/* start collecting the number to the decimal point */	gotmant = 0;	for (;;)	{		c = *p;		if (c < '0' || c > '9')			break;		v = v * 10.0 + (c - '0');		gotmant++;		p++;	}	/* check for fractional part */	if (c == '.')	{		fact = 1.0;		for (;;)		{			c = *++p;			if (c < '0' || c > '9')				break;			fact *= 0.1;			v += (c - '0') * fact;			gotmant++;		}	}	/* skip blanks before possible exponent */	while ((c = *p) != '\0')	{		if (c != ' ')			break;		p++;	}	/* test for exponent */	if (c == 'e' || c == 'E')	{		p++;		expon = pg_atoi(p, sizeof(expon), '\0');		if (!gotmant)			v = 1.0;		fact = expon;		v *= pow(10.0, fact);	}	else	{		/* if no exponent, then nothing */		if (c != 0)			return -1;	}	/* store the result and exit */	if (minus)		v = -v;	*val = v;	return 0;}#endif

⌨️ 快捷键说明

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