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

📄 atof-generic.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
      precision = (address_of_generic_floating_point_number -> high		   - address_of_generic_floating_point_number -> low		   + 1		   );		/* Number of destination littlenums. */				/* Includes guard bits (two littlenums worth) */      maximum_useful_digits = (  ((double) (precision - 2))			       * ((double) (LITTLENUM_NUMBER_OF_BITS))			       / (LOG_TO_BASE_2_OF_10)			       )	+ 2;			/* 2 :: guard digits. */      if (number_of_digits_available > maximum_useful_digits)	{	  number_of_digits_to_use = maximum_useful_digits;	}      else	{	  number_of_digits_to_use = number_of_digits_available;	}      decimal_exponent += number_of_digits_before_decimal - number_of_digits_to_use;      more_than_enough_bits_for_digits	= ((((double)number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1);      more_than_enough_littlenums_for_digits	= (  more_than_enough_bits_for_digits	   / LITTLENUM_NUMBER_OF_BITS	   )	  + 2;            /*       * Compute (digits) part. In "12.34E56" this is the "1234" part.       * Arithmetic is exact here. If no digits are supplied then       * this part is a 0 valued binary integer.       * Allocate room to build up the binary number as littlenums.       * We want this memory to disappear when we leave this function.       * Assume no alignment problems => (room for n objects) ==       * n * (room for 1 object).       */            size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;      size_of_digits_in_chars = size_of_digits_in_littlenums	* sizeof( LITTLENUM_TYPE );      digits_binary_low = (LITTLENUM_TYPE *)	alloca (size_of_digits_in_chars);      bzero ((char *)digits_binary_low, size_of_digits_in_chars);      /* Digits_binary_low[] is allocated and zeroed. */            {	/*	 * Parse the decimal digits as if * digits_low was in the units position.	 * Emit a binary number into digits_binary_low[].	 *	 * Use a large-precision version of:	 * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit	 */	char *		p;	char		c;	int		count;	/* Number of useful digits left to scan. */	for (p = first_digit, count = number_of_digits_to_use;	     count;	     p ++,  -- count)	  {	    c = * p;	    if (isdigit(c))	      {		/*		 * Multiply by 10. Assume can never overflow.		 * Add this digit to digits_binary_low[].		 */		long int	carry;		LITTLENUM_TYPE *	littlenum_pointer;		LITTLENUM_TYPE *	littlenum_limit;		littlenum_limit		  =     digits_binary_low		    +   more_than_enough_littlenums_for_digits		      - 1;		carry = c - '0';	/* char -> binary */		for (littlenum_pointer = digits_binary_low;		     littlenum_pointer <= littlenum_limit;		     littlenum_pointer ++)		  {		    long int	work;		    		    work = carry + 10 * (long)(*littlenum_pointer);		    * littlenum_pointer = work & LITTLENUM_MASK;		    carry = work >> LITTLENUM_NUMBER_OF_BITS;		  }		if (carry != 0)		  {		    /*		     * We have a GROSS internal error.		     * This should never happen.		     */		    abort();	/* RMS prefers abort() to any message. */		  }	      }	    else	      {		++ count;	/* '.' doesn't alter digits used count. */	      }		/* if valid digit */	  }			/* for each digit */      }      /*       * Digits_binary_low[] properly encodes the value of the digits.       * Forget about any high-order littlenums that are 0.       */      while (digits_binary_low [size_of_digits_in_littlenums - 1] == 0	     && size_of_digits_in_littlenums >= 2)	  size_of_digits_in_littlenums --;      digits_flonum . low	= digits_binary_low;      digits_flonum . high	= digits_binary_low + size_of_digits_in_littlenums - 1;      digits_flonum . leader	= digits_flonum . high;      digits_flonum . exponent	= 0;      /*       * The value of digits_flonum . sign should not be important.       * We have already decided the output's sign.       * We trust that the sign won't influence the other parts of the number!       * So we give it a value for these reasons:       * (1) courtesy to humans reading/debugging       *     these numbers so they don't get excited about strange values       * (2) in future there may be more meaning attached to sign,       *     and what was       *     harmless noise may become disruptive, ill-conditioned (or worse)       *     input.       */      digits_flonum . sign	= '+';      {	/*	 * Compute the mantssa (& exponent) of the power of 10.	 * If sucessful, then multiply the power of 10 by the digits	 * giving return_binary_mantissa and return_binary_exponent.	 */	LITTLENUM_TYPE *power_binary_low;	int		decimal_exponent_is_negative;				/* This refers to the "-56" in "12.34E-56". */				/* FALSE: decimal_exponent is positive (or 0) */				/* TRUE:  decimal_exponent is negative */	FLONUM_TYPE	temporary_flonum;	LITTLENUM_TYPE *temporary_binary_low;	int		size_of_power_in_littlenums;	int		size_of_power_in_chars;	size_of_power_in_littlenums = precision;/* Precision has a built-in fudge factor so we get a few guard bits. */	decimal_exponent_is_negative = decimal_exponent < 0;	if (decimal_exponent_is_negative)	  {	    decimal_exponent = - decimal_exponent;	  }	/* From now on: the decimal exponent is > 0. Its sign is seperate. */		size_of_power_in_chars	  =   size_of_power_in_littlenums	    * sizeof( LITTLENUM_TYPE ) + 2;	power_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars );	temporary_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars );	bzero ((char *)power_binary_low, size_of_power_in_chars);	* power_binary_low = 1;	power_of_10_flonum . exponent	= 0;	power_of_10_flonum . low	= power_binary_low;	power_of_10_flonum . leader	= power_binary_low;	power_of_10_flonum . high	= power_binary_low	+ size_of_power_in_littlenums - 1;	power_of_10_flonum . sign	= '+';	temporary_flonum . low	= temporary_binary_low;	temporary_flonum . high	= temporary_binary_low		+ size_of_power_in_littlenums - 1;	/*	 * (power) == 1.	 * Space for temporary_flonum allocated.	 */		/*	 * ...	 *	 * WHILE	more bits	 * DO	find next bit (with place value)	 *	multiply into power mantissa	 * OD	 */	{	  int		place_number_limit;				/* Any 10^(2^n) whose "n" exceeds this */				/* value will fall off the end of */				/* flonum_XXXX_powers_of_ten[]. */	  int		place_number;	  const FLONUM_TYPE * multiplicand; /* -> 10^(2^n) */	  place_number_limit = table_size_of_flonum_powers_of_ten;	  multiplicand	    = (  decimal_exponent_is_negative	       ? flonum_negative_powers_of_ten	       : flonum_positive_powers_of_ten);	  for (place_number = 1;	/* Place value of this bit of exponent. */	       decimal_exponent;	/* Quit when no more 1 bits in exponent. */	       decimal_exponent >>= 1	       , place_number ++)	    {	      if (decimal_exponent & 1)		{		  if (place_number > place_number_limit)		    {		      /*		       * The decimal exponent has a magnitude so great that		       * our tables can't help us fragment it.  Although this		       * routine is in error because it can't imagine a		       * number that big, signal an error as if it is the		       * user's fault for presenting such a big number.		       */		      return_value = ERROR_EXPONENT_OVERFLOW;		      /*		       * quit out of loop gracefully		       */		      decimal_exponent = 0;		    }		  else		    {#ifdef TRACEprintf("before multiply, place_number = %d., power_of_10_flonum:\n", place_number);flonum_print( & power_of_10_flonum );(void)putchar('\n');#endif		      flonum_multip (multiplicand + place_number, & power_of_10_flonum, & temporary_flonum);		      flonum_copy (& temporary_flonum, & power_of_10_flonum);		    }		/* If this bit of decimal_exponent was computable.*/		}			/* If this bit of decimal_exponent was set. */	    }			/* For each bit of binary representation of exponent */#ifdef TRACEprintf( " after computing power_of_10_flonum: " );flonum_print( & power_of_10_flonum );(void)putchar('\n');#endif	}      }      /*       * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).       * It may be the number 1, in which case we don't NEED to multiply.       *       * Multiply (decimal digits) by power_of_10_flonum.       */      flonum_multip (& power_of_10_flonum, & digits_flonum, address_of_generic_floating_point_number);      /* Assert sign of the number we made is '+'. */      address_of_generic_floating_point_number -> sign = digits_sign_char;    }				/* If we had any significant digits. */  return (return_value);}				/* atof_generic () *//* end: atof_generic.c */

⌨️ 快捷键说明

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