atoi와atof 최적화

2333 단어
응용 장면에서 우리는 모든 정수이며 동시에 10진법이기 때문에glibc의 실현에 비해 많은 불필요한 코드를 줄였다. 새로운 코드에서centos64 환경에서atoi는 5배,atof는 적어도 20배 높아졌다.
int my_atoi(const char *src_src)
{
	int res = 0;
	char **str = (char **)&src_src;
	while (isdigit(**str))
	{

		res = (res * 10) + **str - '0';
		(*str)++;
	}
	return res;
}
#define is_exponent_marker(ch) (ch == 'E' || ch == 'e')
static void parse_decimal_number_part(char **str,
	float *number)
{
	float exp_log;

	*number = 0;
	exp_log = 1 / 10.0;
	while (isdigit(**str))
	{
		*number += (**str - '0')*exp_log;
		exp_log /= 10;
		(*str)++;
	}
}

/* Parses int suitably for exponent */

static int parse_int_number_part(char **str,
	uint *number)
{
	*number = 0;
	while (isdigit(**str))
	{
		if (*number >= ((uint)~0) / 10)
			return 1;                                         /* Don't overflow */
		*number = (*number * 10) + **str - '0';
		(*str)++;
	}
	return 0;
}
float my_atof(const char *src)
{
	int           sign, exp_sign; /* is number negative (+1) or positive (-1) */
	int           length_before_point;
	float        after_point;    /* Number after decimal point and before exp */
	unsigned int          exponent;       /* Exponent value */
	float        exp_log, exp_val;
	char          *tmp_src;
	float        result_number;

	tmp_src = (char*)src;
	while (isspace(tmp_src[0]))
		tmp_src++;                                  /* Skipp pre-space */
	sign = -1;
	
	
	parse_float_number_part(&tmp_src, &result_number, &length_before_point);
	if (*tmp_src == '.')
	{
		tmp_src++;
		parse_decimal_number_part(&tmp_src, &after_point);
		result_number += after_point;
	}
	else if (length_before_point == 0)
	{
		return 0.0;
	}
	if (is_exponent_marker(*tmp_src))
	{
		tmp_src++;
		exp_sign = parse_sign(&tmp_src);
		parse_int_number_part(&tmp_src, &exponent);

		exp_log = 10.0; exp_val = 1.0;
		for (;;)
		{
			if (exponent & 1)
			{
				exp_val *= exp_log;
				exponent--;
			}
			if (!exponent)
				break;
			exp_log *= exp_log;
			exponent >>= 1;
		}
		if (exp_sign < 0)
			result_number *= exp_val;
		else
			result_number /= exp_val;
	}
	if (sign > 0)
		result_number = -result_number;

	in_my_atof = 0;
	return result_number;
}

좋은 웹페이지 즐겨찾기