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

📄 atof-generic.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* atof_generic.c - turn a string of digits into a Flonum   Copyright (C) 1987 Free Software Foundation, Inc.This file is part of GAS, the GNU Assembler.GAS is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GAS is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GAS; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */#include <ctype.h>#include "flonum.h"#ifdef __GNUC__#define alloca __builtin_alloca#else#ifdef sparc#include <alloca.h>#endif#endif#ifdef USG#define bzero(s,n) memset(s,0,n)#define index strchr#endif#define	FALSE (0)#define TRUE  (1)char *index();/***********************************************************************\*									**	Given a string of decimal digits , with optional decimal	**	mark and optional decimal exponent (place value) of the		**	lowest_order decimal digit: produce a floating point		**	number. The number is 'generic' floating point: our		**	caller will encode it for a specific machine architecture.	**									**	Assumptions							**		uses base (radix) 2					**		this machine uses 2's complement binary integers	**		target flonums use "      "         "       "		**		target flonums exponents fit in a long int		**									*\***********************************************************************//*			Syntax:<flonum>		::=	<optional-sign> <decimal-number> <optional-exponent><optional-sign>		::=	'+' | '-' | {empty}<decimal-number>	::=	  <integer>				| <integer> <radix-character> 				| <integer> <radix-character> <integer> 				|	    <radix-character> <integer><optional-exponent>	::=	{empty} | <exponent-character> <optional-sign> <integer> <integer>		::=	<digit> | <digit> <integer><digit>			::=	'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'<exponent-character>	::=	{one character from "string_of_decimal_exponent_marks"}<radix-character>	::=	{one character from "string_of_decimal_marks"}*/int				/* 0 if OK */atof_generic (	address_of_string_pointer, /* return pointer to just AFTER number we read. */	string_of_decimal_marks, /* At most one per number. */	string_of_decimal_exponent_marks,	address_of_generic_floating_point_number)     char * *		address_of_string_pointer;     const char *	string_of_decimal_marks;     const char *	string_of_decimal_exponent_marks;     FLONUM_TYPE *	address_of_generic_floating_point_number;{  int			return_value; /* 0 means OK. */  char *		first_digit;  /* char *		last_digit; JF unused */  int			number_of_digits_before_decimal;  int			number_of_digits_after_decimal;  long int		decimal_exponent;  int			number_of_digits_available;  char			digits_sign_char;  {    /*     * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.     * It would be simpler to modify the string, but we don't; just to be nice     * to caller.     * We need to know how many digits we have, so we can allocate space for     * the digits' value.     */    char *		p;    char		c;    int			seen_significant_digit;    first_digit = * address_of_string_pointer;    c= *first_digit;    if (c=='-' || c=='+')      {	digits_sign_char = c;        first_digit ++;      }    else	digits_sign_char = '+';    if(   (first_digit[0]=='n' || first_digit[0]=='N')       && (first_digit[1]=='a' || first_digit[1]=='A')       && (first_digit[2]=='n' || first_digit[2]=='N')) {      address_of_generic_floating_point_number->sign=0;      address_of_generic_floating_point_number->exponent=0;      address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low;      (*address_of_string_pointer)=first_digit+3;      return 0;    }    if(   (first_digit[0]=='i' || first_digit[0]=='I')        && (first_digit[1]=='n' || first_digit[1]=='N')       && (first_digit[2]=='f' || first_digit[2]=='F')) {      address_of_generic_floating_point_number->sign= digits_sign_char=='+' ? 'P' : 'N';      address_of_generic_floating_point_number->exponent=0;      address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low;      if(   (first_digit[3]=='i' || first_digit[3]=='I')         && (first_digit[4]=='n' || first_digit[4]=='N')	 && (first_digit[5]=='i' || first_digit[5]=='I')	 && (first_digit[6]=='t' || first_digit[6]=='T')	 && (first_digit[7]=='y' || first_digit[7]=='Y'))	  (*address_of_string_pointer)=first_digit+8;      else	  (*address_of_string_pointer)=first_digit+3;      return 0;    }    number_of_digits_before_decimal = 0;    number_of_digits_after_decimal = 0;    decimal_exponent = 0;    seen_significant_digit = FALSE;    for (p = first_digit;	 (c = * p)	 && (!c || ! index (string_of_decimal_marks,          c) )	 && (!c || ! index (string_of_decimal_exponent_marks, c) );	 p ++)      {	if (isdigit(c))	  {	    if (seen_significant_digit || c > '0')	      {		number_of_digits_before_decimal ++;		seen_significant_digit = TRUE;	      }	    else	      {	        first_digit++;	      }	  }	else	  {	    break;		/* p -> char after pre-decimal digits. */	  }      }				/* For each digit before decimal mark. */    if (c && index (string_of_decimal_marks, c))      {	for (p ++;	     (c = * p)	     && (!c || ! index (string_of_decimal_exponent_marks, c) );	     p ++)	  {	    if (isdigit(c))	      {		number_of_digits_after_decimal ++; /* This may be retracted below. */		if (/* seen_significant_digit || */ c > '0')		  {		    seen_significant_digit = TRUE;		  }	      }	    else	      {		if ( ! seen_significant_digit)		  {		    number_of_digits_after_decimal = 0;		  }		break;	      }	  }			/* For each digit after decimal mark. */      }      while(number_of_digits_after_decimal && first_digit[number_of_digits_before_decimal+number_of_digits_after_decimal]=='0')	--number_of_digits_after_decimal;/*    last_digit = p; JF unused */        if (c && index (string_of_decimal_exponent_marks, c) )      {	char		digits_exponent_sign_char;		c = * ++ p;	if (c && index ("+-",c))	  {	    digits_exponent_sign_char = c;	    c = * ++ p;	  }	else	  {	    digits_exponent_sign_char = '+';	  }	for (;	     (c);	     c = * ++ p)	  {	    if (isdigit(c))	      {		decimal_exponent = decimal_exponent * 10 + c - '0';		/*		 * BUG! If we overflow here, we lose!		 */	      }	    else	      {		break;	      }	  }	if (digits_exponent_sign_char == '-')	  {	    decimal_exponent = - decimal_exponent;	  }      }    * address_of_string_pointer = p;  }  number_of_digits_available =    number_of_digits_before_decimal      + number_of_digits_after_decimal;  return_value = 0;  if (number_of_digits_available == 0)    {      address_of_generic_floating_point_number -> exponent = 0;	/* Not strictly necessary */      address_of_generic_floating_point_number -> leader	= -1 + address_of_generic_floating_point_number -> low;      address_of_generic_floating_point_number -> sign = digits_sign_char;      /* We have just concocted (+/-)0.0E0 */    }  else    {      LITTLENUM_TYPE *	digits_binary_low;      int		precision;      int		maximum_useful_digits;      int		number_of_digits_to_use;      int		more_than_enough_bits_for_digits;      int		more_than_enough_littlenums_for_digits;      int		size_of_digits_in_littlenums;      int		size_of_digits_in_chars;      FLONUM_TYPE	power_of_10_flonum;      FLONUM_TYPE	digits_flonum;

⌨️ 快捷键说明

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