133965Sjdp/* atof_generic.c - turn a string of digits into a Flonum
2218822Sdim   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000,
3218822Sdim   2001, 2003, 2005, 2006 Free Software Foundation, Inc.
433965Sjdp
533965Sjdp   This file is part of GAS, the GNU Assembler.
633965Sjdp
733965Sjdp   GAS is free software; you can redistribute it and/or modify
833965Sjdp   it under the terms of the GNU General Public License as published by
933965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1033965Sjdp   any later version.
1133965Sjdp
1233965Sjdp   GAS is distributed in the hope that it will be useful,
1333965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1433965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965Sjdp   GNU General Public License for more details.
1633965Sjdp
1733965Sjdp   You should have received a copy of the GNU General Public License
1877298Sobrien   along with GAS; see the file COPYING.  If not, write to the Free
19218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20218822Sdim   02110-1301, USA.  */
2133965Sjdp
2233965Sjdp#include "as.h"
2389857Sobrien#include "safe-ctype.h"
2433965Sjdp
2533965Sjdp#ifndef FALSE
2633965Sjdp#define FALSE (0)
2733965Sjdp#endif
2833965Sjdp#ifndef TRUE
2933965Sjdp#define TRUE  (1)
3033965Sjdp#endif
3133965Sjdp
3233965Sjdp#ifdef TRACE
33130561Sobrienstatic void flonum_print (const FLONUM_TYPE *);
3433965Sjdp#endif
3533965Sjdp
3633965Sjdp#define ASSUME_DECIMAL_MARK_IS_DOT
3733965Sjdp
3833965Sjdp/***********************************************************************\
3933965Sjdp *									*
4033965Sjdp *	Given a string of decimal digits , with optional decimal	*
4133965Sjdp *	mark and optional decimal exponent (place value) of the		*
4233965Sjdp *	lowest_order decimal digit: produce a floating point		*
4333965Sjdp *	number. The number is 'generic' floating point: our		*
4433965Sjdp *	caller will encode it for a specific machine architecture.	*
4533965Sjdp *									*
4633965Sjdp *	Assumptions							*
4733965Sjdp *		uses base (radix) 2					*
4833965Sjdp *		this machine uses 2's complement binary integers	*
4933965Sjdp *		target flonums use "      "         "       "		*
5033965Sjdp *		target flonums exponents fit in a long			*
5133965Sjdp *									*
5233965Sjdp \***********************************************************************/
5333965Sjdp
5433965Sjdp/*
5533965Sjdp
5633965Sjdp  Syntax:
5733965Sjdp
5833965Sjdp  <flonum> ::= <optional-sign> <decimal-number> <optional-exponent>
5933965Sjdp  <optional-sign> ::= '+' | '-' | {empty}
6033965Sjdp  <decimal-number> ::= <integer>
6133965Sjdp  | <integer> <radix-character>
6233965Sjdp  | <integer> <radix-character> <integer>
6333965Sjdp  | <radix-character> <integer>
6433965Sjdp
6533965Sjdp  <optional-exponent> ::= {empty}
6633965Sjdp  | <exponent-character> <optional-sign> <integer>
6733965Sjdp
6833965Sjdp  <integer> ::= <digit> | <digit> <integer>
6933965Sjdp  <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
7033965Sjdp  <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"}
7133965Sjdp  <radix-character> ::= {one character from "string_of_decimal_marks"}
7233965Sjdp
7333965Sjdp  */
7433965Sjdp
7533965Sjdpint
76130561Sobrienatof_generic (/* return pointer to just AFTER number we read.  */
77130561Sobrien	      char **address_of_string_pointer,
78130561Sobrien	      /* At most one per number.  */
79130561Sobrien	      const char *string_of_decimal_marks,
80130561Sobrien	      const char *string_of_decimal_exponent_marks,
81130561Sobrien	      FLONUM_TYPE *address_of_generic_floating_point_number)
8233965Sjdp{
8377298Sobrien  int return_value;		/* 0 means OK.  */
8433965Sjdp  char *first_digit;
8538889Sjdp  unsigned int number_of_digits_before_decimal;
8638889Sjdp  unsigned int number_of_digits_after_decimal;
8733965Sjdp  long decimal_exponent;
8838889Sjdp  unsigned int number_of_digits_available;
8933965Sjdp  char digits_sign_char;
9033965Sjdp
9133965Sjdp  /*
9233965Sjdp   * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
9333965Sjdp   * It would be simpler to modify the string, but we don't; just to be nice
9433965Sjdp   * to caller.
9533965Sjdp   * We need to know how many digits we have, so we can allocate space for
9633965Sjdp   * the digits' value.
9733965Sjdp   */
9833965Sjdp
9933965Sjdp  char *p;
10033965Sjdp  char c;
10133965Sjdp  int seen_significant_digit;
10233965Sjdp
10333965Sjdp#ifdef ASSUME_DECIMAL_MARK_IS_DOT
10433965Sjdp  assert (string_of_decimal_marks[0] == '.'
10533965Sjdp	  && string_of_decimal_marks[1] == 0);
10633965Sjdp#define IS_DECIMAL_MARK(c)	((c) == '.')
10733965Sjdp#else
10833965Sjdp#define IS_DECIMAL_MARK(c)	(0 != strchr (string_of_decimal_marks, (c)))
10933965Sjdp#endif
11033965Sjdp
11133965Sjdp  first_digit = *address_of_string_pointer;
11233965Sjdp  c = *first_digit;
11333965Sjdp
11433965Sjdp  if (c == '-' || c == '+')
11533965Sjdp    {
11633965Sjdp      digits_sign_char = c;
11733965Sjdp      first_digit++;
11833965Sjdp    }
11933965Sjdp  else
12033965Sjdp    digits_sign_char = '+';
12133965Sjdp
12233965Sjdp  switch (first_digit[0])
12333965Sjdp    {
12433965Sjdp    case 'n':
12533965Sjdp    case 'N':
12633965Sjdp      if (!strncasecmp ("nan", first_digit, 3))
12733965Sjdp	{
12833965Sjdp	  address_of_generic_floating_point_number->sign = 0;
12933965Sjdp	  address_of_generic_floating_point_number->exponent = 0;
13033965Sjdp	  address_of_generic_floating_point_number->leader =
13133965Sjdp	    address_of_generic_floating_point_number->low;
13233965Sjdp	  *address_of_string_pointer = first_digit + 3;
13333965Sjdp	  return 0;
13433965Sjdp	}
13533965Sjdp      break;
13633965Sjdp
13733965Sjdp    case 'i':
13833965Sjdp    case 'I':
13933965Sjdp      if (!strncasecmp ("inf", first_digit, 3))
14033965Sjdp	{
14133965Sjdp	  address_of_generic_floating_point_number->sign =
14233965Sjdp	    digits_sign_char == '+' ? 'P' : 'N';
14333965Sjdp	  address_of_generic_floating_point_number->exponent = 0;
14433965Sjdp	  address_of_generic_floating_point_number->leader =
14533965Sjdp	    address_of_generic_floating_point_number->low;
14633965Sjdp
14733965Sjdp	  first_digit += 3;
14833965Sjdp	  if (!strncasecmp ("inity", first_digit, 5))
14933965Sjdp	    first_digit += 5;
15033965Sjdp
15133965Sjdp	  *address_of_string_pointer = first_digit;
15233965Sjdp
15333965Sjdp	  return 0;
15433965Sjdp	}
15533965Sjdp      break;
15633965Sjdp    }
15733965Sjdp
15833965Sjdp  number_of_digits_before_decimal = 0;
15933965Sjdp  number_of_digits_after_decimal = 0;
16033965Sjdp  decimal_exponent = 0;
16133965Sjdp  seen_significant_digit = 0;
16233965Sjdp  for (p = first_digit;
16333965Sjdp       (((c = *p) != '\0')
16433965Sjdp	&& (!c || !IS_DECIMAL_MARK (c))
16533965Sjdp	&& (!c || !strchr (string_of_decimal_exponent_marks, c)));
16633965Sjdp       p++)
16733965Sjdp    {
16889857Sobrien      if (ISDIGIT (c))
16933965Sjdp	{
17033965Sjdp	  if (seen_significant_digit || c > '0')
17133965Sjdp	    {
17233965Sjdp	      ++number_of_digits_before_decimal;
17333965Sjdp	      seen_significant_digit = 1;
17433965Sjdp	    }
17533965Sjdp	  else
17633965Sjdp	    {
17733965Sjdp	      first_digit++;
17833965Sjdp	    }
17933965Sjdp	}
18033965Sjdp      else
18133965Sjdp	{
18277298Sobrien	  break;		/* p -> char after pre-decimal digits.  */
18333965Sjdp	}
18477298Sobrien    }				/* For each digit before decimal mark.  */
18533965Sjdp
18633965Sjdp#ifndef OLD_FLOAT_READS
18733965Sjdp  /* Ignore trailing 0's after the decimal point.  The original code here
18833965Sjdp   * (ifdef'd out) does not do this, and numbers like
18933965Sjdp   *	4.29496729600000000000e+09	(2**31)
19033965Sjdp   * come out inexact for some reason related to length of the digit
19133965Sjdp   * string.
19233965Sjdp   */
19333965Sjdp  if (c && IS_DECIMAL_MARK (c))
19433965Sjdp    {
19538889Sjdp      unsigned int zeros = 0;	/* Length of current string of zeros */
19633965Sjdp
19789857Sobrien      for (p++; (c = *p) && ISDIGIT (c); p++)
19833965Sjdp	{
19933965Sjdp	  if (c == '0')
20033965Sjdp	    {
20133965Sjdp	      zeros++;
20233965Sjdp	    }
20333965Sjdp	  else
20433965Sjdp	    {
20533965Sjdp	      number_of_digits_after_decimal += 1 + zeros;
20633965Sjdp	      zeros = 0;
20733965Sjdp	    }
20833965Sjdp	}
20933965Sjdp    }
21033965Sjdp#else
21133965Sjdp  if (c && IS_DECIMAL_MARK (c))
21233965Sjdp    {
21333965Sjdp      for (p++;
21433965Sjdp	   (((c = *p) != '\0')
21533965Sjdp	    && (!c || !strchr (string_of_decimal_exponent_marks, c)));
21633965Sjdp	   p++)
21733965Sjdp	{
21889857Sobrien	  if (ISDIGIT (c))
21933965Sjdp	    {
22077298Sobrien	      /* This may be retracted below.  */
22133965Sjdp	      number_of_digits_after_decimal++;
22233965Sjdp
22333965Sjdp	      if ( /* seen_significant_digit || */ c > '0')
22433965Sjdp		{
22533965Sjdp		  seen_significant_digit = TRUE;
22633965Sjdp		}
22733965Sjdp	    }
22833965Sjdp	  else
22933965Sjdp	    {
23033965Sjdp	      if (!seen_significant_digit)
23133965Sjdp		{
23233965Sjdp		  number_of_digits_after_decimal = 0;
23333965Sjdp		}
23433965Sjdp	      break;
23533965Sjdp	    }
23677298Sobrien	}			/* For each digit after decimal mark.  */
23733965Sjdp    }
23833965Sjdp
23933965Sjdp  while (number_of_digits_after_decimal
24033965Sjdp	 && first_digit[number_of_digits_before_decimal
24133965Sjdp			+ number_of_digits_after_decimal] == '0')
24233965Sjdp    --number_of_digits_after_decimal;
24333965Sjdp#endif
24433965Sjdp
24533965Sjdp  if (flag_m68k_mri)
24633965Sjdp    {
24733965Sjdp      while (c == '_')
24833965Sjdp	c = *++p;
24933965Sjdp    }
25033965Sjdp  if (c && strchr (string_of_decimal_exponent_marks, c))
25133965Sjdp    {
25233965Sjdp      char digits_exponent_sign_char;
25333965Sjdp
25433965Sjdp      c = *++p;
25533965Sjdp      if (flag_m68k_mri)
25633965Sjdp	{
25733965Sjdp	  while (c == '_')
25833965Sjdp	    c = *++p;
25933965Sjdp	}
26033965Sjdp      if (c && strchr ("+-", c))
26133965Sjdp	{
26233965Sjdp	  digits_exponent_sign_char = c;
26333965Sjdp	  c = *++p;
26433965Sjdp	}
26533965Sjdp      else
26633965Sjdp	{
26733965Sjdp	  digits_exponent_sign_char = '+';
26833965Sjdp	}
26933965Sjdp
27033965Sjdp      for (; (c); c = *++p)
27133965Sjdp	{
27289857Sobrien	  if (ISDIGIT (c))
27333965Sjdp	    {
27433965Sjdp	      decimal_exponent = decimal_exponent * 10 + c - '0';
27533965Sjdp	      /*
27633965Sjdp	       * BUG! If we overflow here, we lose!
27733965Sjdp	       */
27833965Sjdp	    }
27933965Sjdp	  else
28033965Sjdp	    {
28133965Sjdp	      break;
28233965Sjdp	    }
28333965Sjdp	}
28433965Sjdp
28533965Sjdp      if (digits_exponent_sign_char == '-')
28633965Sjdp	{
28733965Sjdp	  decimal_exponent = -decimal_exponent;
28833965Sjdp	}
28933965Sjdp    }
29033965Sjdp
29133965Sjdp  *address_of_string_pointer = p;
29233965Sjdp
29333965Sjdp  number_of_digits_available =
29433965Sjdp    number_of_digits_before_decimal + number_of_digits_after_decimal;
29533965Sjdp  return_value = 0;
29633965Sjdp  if (number_of_digits_available == 0)
29733965Sjdp    {
29833965Sjdp      address_of_generic_floating_point_number->exponent = 0;	/* Not strictly necessary */
29933965Sjdp      address_of_generic_floating_point_number->leader
30033965Sjdp	= -1 + address_of_generic_floating_point_number->low;
30133965Sjdp      address_of_generic_floating_point_number->sign = digits_sign_char;
30233965Sjdp      /* We have just concocted (+/-)0.0E0 */
30333965Sjdp
30433965Sjdp    }
30533965Sjdp  else
30633965Sjdp    {
30777298Sobrien      int count;		/* Number of useful digits left to scan.  */
30833965Sjdp
30933965Sjdp      LITTLENUM_TYPE *digits_binary_low;
31033965Sjdp      unsigned int precision;
31133965Sjdp      unsigned int maximum_useful_digits;
31233965Sjdp      unsigned int number_of_digits_to_use;
31333965Sjdp      unsigned int more_than_enough_bits_for_digits;
31433965Sjdp      unsigned int more_than_enough_littlenums_for_digits;
31533965Sjdp      unsigned int size_of_digits_in_littlenums;
31633965Sjdp      unsigned int size_of_digits_in_chars;
31733965Sjdp      FLONUM_TYPE power_of_10_flonum;
31833965Sjdp      FLONUM_TYPE digits_flonum;
31933965Sjdp
32033965Sjdp      precision = (address_of_generic_floating_point_number->high
32133965Sjdp		   - address_of_generic_floating_point_number->low
32277298Sobrien		   + 1);	/* Number of destination littlenums.  */
32333965Sjdp
32433965Sjdp      /* Includes guard bits (two littlenums worth) */
32533965Sjdp      maximum_useful_digits = (((precision - 2))
32633965Sjdp			       * ( (LITTLENUM_NUMBER_OF_BITS))
32733965Sjdp			       * 1000000 / 3321928)
32877298Sobrien	+ 2;			/* 2 :: guard digits.  */
32933965Sjdp
33033965Sjdp      if (number_of_digits_available > maximum_useful_digits)
33133965Sjdp	{
33233965Sjdp	  number_of_digits_to_use = maximum_useful_digits;
33333965Sjdp	}
33433965Sjdp      else
33533965Sjdp	{
33633965Sjdp	  number_of_digits_to_use = number_of_digits_available;
33733965Sjdp	}
33833965Sjdp
33933965Sjdp      /* Cast these to SIGNED LONG first, otherwise, on systems with
34033965Sjdp	 LONG wider than INT (such as Alpha OSF/1), unsignedness may
34133965Sjdp	 cause unexpected results.  */
34233965Sjdp      decimal_exponent += ((long) number_of_digits_before_decimal
34333965Sjdp			   - (long) number_of_digits_to_use);
34433965Sjdp
34533965Sjdp      more_than_enough_bits_for_digits
34633965Sjdp	= (number_of_digits_to_use * 3321928 / 1000000 + 1);
34733965Sjdp
34833965Sjdp      more_than_enough_littlenums_for_digits
34933965Sjdp	= (more_than_enough_bits_for_digits
35033965Sjdp	   / LITTLENUM_NUMBER_OF_BITS)
35133965Sjdp	+ 2;
35233965Sjdp
35333965Sjdp      /* Compute (digits) part. In "12.34E56" this is the "1234" part.
35433965Sjdp	 Arithmetic is exact here. If no digits are supplied then this
35533965Sjdp	 part is a 0 valued binary integer.  Allocate room to build up
35633965Sjdp	 the binary number as littlenums.  We want this memory to
35733965Sjdp	 disappear when we leave this function.  Assume no alignment
35833965Sjdp	 problems => (room for n objects) == n * (room for 1
35933965Sjdp	 object).  */
36033965Sjdp
36133965Sjdp      size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
36233965Sjdp      size_of_digits_in_chars = size_of_digits_in_littlenums
36333965Sjdp	* sizeof (LITTLENUM_TYPE);
36433965Sjdp
36533965Sjdp      digits_binary_low = (LITTLENUM_TYPE *)
36633965Sjdp	alloca (size_of_digits_in_chars);
36733965Sjdp
36833965Sjdp      memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);
36933965Sjdp
37077298Sobrien      /* Digits_binary_low[] is allocated and zeroed.  */
37133965Sjdp
37233965Sjdp      /*
37333965Sjdp       * Parse the decimal digits as if * digits_low was in the units position.
37433965Sjdp       * Emit a binary number into digits_binary_low[].
37533965Sjdp       *
37633965Sjdp       * Use a large-precision version of:
37733965Sjdp       * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
37833965Sjdp       */
37933965Sjdp
38033965Sjdp      for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
38133965Sjdp	{
38233965Sjdp	  c = *p;
38389857Sobrien	  if (ISDIGIT (c))
38433965Sjdp	    {
38533965Sjdp	      /*
38633965Sjdp	       * Multiply by 10. Assume can never overflow.
38733965Sjdp	       * Add this digit to digits_binary_low[].
38833965Sjdp	       */
38933965Sjdp
39033965Sjdp	      long carry;
39133965Sjdp	      LITTLENUM_TYPE *littlenum_pointer;
39233965Sjdp	      LITTLENUM_TYPE *littlenum_limit;
39333965Sjdp
39433965Sjdp	      littlenum_limit = digits_binary_low
39533965Sjdp		+ more_than_enough_littlenums_for_digits
39633965Sjdp		- 1;
39733965Sjdp
39833965Sjdp	      carry = c - '0';	/* char -> binary */
39933965Sjdp
40033965Sjdp	      for (littlenum_pointer = digits_binary_low;
40133965Sjdp		   littlenum_pointer <= littlenum_limit;
40233965Sjdp		   littlenum_pointer++)
40333965Sjdp		{
40433965Sjdp		  long work;
40533965Sjdp
40633965Sjdp		  work = carry + 10 * (long) (*littlenum_pointer);
40733965Sjdp		  *littlenum_pointer = work & LITTLENUM_MASK;
40833965Sjdp		  carry = work >> LITTLENUM_NUMBER_OF_BITS;
40933965Sjdp		}
41033965Sjdp
41133965Sjdp	      if (carry != 0)
41233965Sjdp		{
41333965Sjdp		  /*
41433965Sjdp		   * We have a GROSS internal error.
41533965Sjdp		   * This should never happen.
41633965Sjdp		   */
41789857Sobrien		  as_fatal (_("failed sanity check"));
41833965Sjdp		}
41933965Sjdp	    }
42033965Sjdp	  else
42133965Sjdp	    {
42277298Sobrien	      ++count;		/* '.' doesn't alter digits used count.  */
42333965Sjdp	    }
42433965Sjdp	}
42533965Sjdp
42633965Sjdp      /*
42733965Sjdp       * Digits_binary_low[] properly encodes the value of the digits.
42833965Sjdp       * Forget about any high-order littlenums that are 0.
42933965Sjdp       */
43033965Sjdp      while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0
43133965Sjdp	     && size_of_digits_in_littlenums >= 2)
43233965Sjdp	size_of_digits_in_littlenums--;
43333965Sjdp
43433965Sjdp      digits_flonum.low = digits_binary_low;
43533965Sjdp      digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1;
43633965Sjdp      digits_flonum.leader = digits_flonum.high;
43733965Sjdp      digits_flonum.exponent = 0;
43833965Sjdp      /*
43933965Sjdp       * The value of digits_flonum . sign should not be important.
44033965Sjdp       * We have already decided the output's sign.
44133965Sjdp       * We trust that the sign won't influence the other parts of the number!
44233965Sjdp       * So we give it a value for these reasons:
44333965Sjdp       * (1) courtesy to humans reading/debugging
44433965Sjdp       *     these numbers so they don't get excited about strange values
44533965Sjdp       * (2) in future there may be more meaning attached to sign,
44633965Sjdp       *     and what was
44733965Sjdp       *     harmless noise may become disruptive, ill-conditioned (or worse)
44833965Sjdp       *     input.
44933965Sjdp       */
45033965Sjdp      digits_flonum.sign = '+';
45133965Sjdp
45233965Sjdp      {
45333965Sjdp	/*
45433965Sjdp	 * Compute the mantssa (& exponent) of the power of 10.
455130561Sobrien	 * If successful, then multiply the power of 10 by the digits
45633965Sjdp	 * giving return_binary_mantissa and return_binary_exponent.
45733965Sjdp	 */
45833965Sjdp
45933965Sjdp	LITTLENUM_TYPE *power_binary_low;
46033965Sjdp	int decimal_exponent_is_negative;
46177298Sobrien	/* This refers to the "-56" in "12.34E-56".  */
46233965Sjdp	/* FALSE: decimal_exponent is positive (or 0) */
46333965Sjdp	/* TRUE:  decimal_exponent is negative */
46433965Sjdp	FLONUM_TYPE temporary_flonum;
46533965Sjdp	LITTLENUM_TYPE *temporary_binary_low;
46633965Sjdp	unsigned int size_of_power_in_littlenums;
46733965Sjdp	unsigned int size_of_power_in_chars;
46833965Sjdp
46933965Sjdp	size_of_power_in_littlenums = precision;
47077298Sobrien	/* Precision has a built-in fudge factor so we get a few guard bits.  */
47133965Sjdp
47233965Sjdp	decimal_exponent_is_negative = decimal_exponent < 0;
47333965Sjdp	if (decimal_exponent_is_negative)
47433965Sjdp	  {
47533965Sjdp	    decimal_exponent = -decimal_exponent;
47633965Sjdp	  }
47733965Sjdp
47877298Sobrien	/* From now on: the decimal exponent is > 0. Its sign is separate.  */
47933965Sjdp
48033965Sjdp	size_of_power_in_chars = size_of_power_in_littlenums
48133965Sjdp	  * sizeof (LITTLENUM_TYPE) + 2;
48233965Sjdp
48333965Sjdp	power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
48433965Sjdp	temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
48533965Sjdp	memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
48633965Sjdp	*power_binary_low = 1;
48733965Sjdp	power_of_10_flonum.exponent = 0;
48833965Sjdp	power_of_10_flonum.low = power_binary_low;
48933965Sjdp	power_of_10_flonum.leader = power_binary_low;
49033965Sjdp	power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1;
49133965Sjdp	power_of_10_flonum.sign = '+';
49233965Sjdp	temporary_flonum.low = temporary_binary_low;
49333965Sjdp	temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1;
49433965Sjdp	/*
49533965Sjdp	 * (power) == 1.
49633965Sjdp	 * Space for temporary_flonum allocated.
49733965Sjdp	 */
49833965Sjdp
49933965Sjdp	/*
50033965Sjdp	 * ...
50133965Sjdp	 *
50233965Sjdp	 * WHILE	more bits
50333965Sjdp	 * DO	find next bit (with place value)
50433965Sjdp	 *	multiply into power mantissa
50533965Sjdp	 * OD
50633965Sjdp	 */
50733965Sjdp	{
50833965Sjdp	  int place_number_limit;
50933965Sjdp	  /* Any 10^(2^n) whose "n" exceeds this */
51033965Sjdp	  /* value will fall off the end of */
51177298Sobrien	  /* flonum_XXXX_powers_of_ten[].  */
51233965Sjdp	  int place_number;
51333965Sjdp	  const FLONUM_TYPE *multiplicand;	/* -> 10^(2^n) */
51433965Sjdp
51533965Sjdp	  place_number_limit = table_size_of_flonum_powers_of_ten;
51633965Sjdp
51733965Sjdp	  multiplicand = (decimal_exponent_is_negative
51833965Sjdp			  ? flonum_negative_powers_of_ten
51933965Sjdp			  : flonum_positive_powers_of_ten);
52033965Sjdp
52177298Sobrien	  for (place_number = 1;/* Place value of this bit of exponent.  */
52277298Sobrien	       decimal_exponent;/* Quit when no more 1 bits in exponent.  */
52333965Sjdp	       decimal_exponent >>= 1, place_number++)
52433965Sjdp	    {
52533965Sjdp	      if (decimal_exponent & 1)
52633965Sjdp		{
52733965Sjdp		  if (place_number > place_number_limit)
52833965Sjdp		    {
52933965Sjdp		      /* The decimal exponent has a magnitude so great
53033965Sjdp			 that our tables can't help us fragment it.
53133965Sjdp			 Although this routine is in error because it
53233965Sjdp			 can't imagine a number that big, signal an
53333965Sjdp			 error as if it is the user's fault for
53433965Sjdp			 presenting such a big number.  */
53533965Sjdp		      return_value = ERROR_EXPONENT_OVERFLOW;
53633965Sjdp		      /* quit out of loop gracefully */
53733965Sjdp		      decimal_exponent = 0;
53833965Sjdp		    }
53933965Sjdp		  else
54033965Sjdp		    {
54133965Sjdp#ifdef TRACE
54233965Sjdp		      printf ("before multiply, place_number = %d., power_of_10_flonum:\n",
54333965Sjdp			      place_number);
54433965Sjdp
54533965Sjdp		      flonum_print (&power_of_10_flonum);
54633965Sjdp		      (void) putchar ('\n');
54733965Sjdp#endif
54833965Sjdp#ifdef TRACE
54933965Sjdp		      printf ("multiplier:\n");
55033965Sjdp		      flonum_print (multiplicand + place_number);
55133965Sjdp		      (void) putchar ('\n');
55233965Sjdp#endif
55333965Sjdp		      flonum_multip (multiplicand + place_number,
55433965Sjdp				     &power_of_10_flonum, &temporary_flonum);
55533965Sjdp#ifdef TRACE
55633965Sjdp		      printf ("after multiply:\n");
55733965Sjdp		      flonum_print (&temporary_flonum);
55833965Sjdp		      (void) putchar ('\n');
55933965Sjdp#endif
56033965Sjdp		      flonum_copy (&temporary_flonum, &power_of_10_flonum);
56133965Sjdp#ifdef TRACE
56233965Sjdp		      printf ("after copy:\n");
56333965Sjdp		      flonum_print (&power_of_10_flonum);
56433965Sjdp		      (void) putchar ('\n');
56533965Sjdp#endif
56633965Sjdp		    } /* If this bit of decimal_exponent was computable.*/
56777298Sobrien		} /* If this bit of decimal_exponent was set.  */
56833965Sjdp	    } /* For each bit of binary representation of exponent */
56933965Sjdp#ifdef TRACE
57033965Sjdp	  printf ("after computing power_of_10_flonum:\n");
57133965Sjdp	  flonum_print (&power_of_10_flonum);
57233965Sjdp	  (void) putchar ('\n');
57333965Sjdp#endif
57433965Sjdp	}
57533965Sjdp
57633965Sjdp      }
57733965Sjdp
57833965Sjdp      /*
57933965Sjdp       * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
58033965Sjdp       * It may be the number 1, in which case we don't NEED to multiply.
58133965Sjdp       *
58233965Sjdp       * Multiply (decimal digits) by power_of_10_flonum.
58333965Sjdp       */
58433965Sjdp
58533965Sjdp      flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
58677298Sobrien      /* Assert sign of the number we made is '+'.  */
58733965Sjdp      address_of_generic_floating_point_number->sign = digits_sign_char;
58833965Sjdp
58933965Sjdp    }
59033965Sjdp  return return_value;
59133965Sjdp}
59233965Sjdp
59333965Sjdp#ifdef TRACE
59433965Sjdpstatic void
59533965Sjdpflonum_print (f)
59633965Sjdp     const FLONUM_TYPE *f;
59733965Sjdp{
59833965Sjdp  LITTLENUM_TYPE *lp;
59933965Sjdp  char littlenum_format[10];
60033965Sjdp  sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2);
60133965Sjdp#define print_littlenum(LP)	(printf (littlenum_format, LP))
60233965Sjdp  printf ("flonum @%p %c e%ld", f, f->sign, f->exponent);
60333965Sjdp  if (f->low < f->high)
60433965Sjdp    for (lp = f->high; lp >= f->low; lp--)
60533965Sjdp      print_littlenum (*lp);
60633965Sjdp  else
60733965Sjdp    for (lp = f->low; lp <= f->high; lp++)
60833965Sjdp      print_littlenum (*lp);
60933965Sjdp  printf ("\n");
61033965Sjdp  fflush (stdout);
61133965Sjdp}
61233965Sjdp#endif
61333965Sjdp
61433965Sjdp/* end of atof_generic.c */
615