xref: /openbsd-src/gnu/usr.bin/binutils-2.17/gas/atof-generic.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* atof_generic.c - turn a string of digits into a Flonum
2*3d8817e4Smiod    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000,
3*3d8817e4Smiod    2001, 2003, 2005 Free Software Foundation, Inc.
4*3d8817e4Smiod 
5*3d8817e4Smiod    This file is part of GAS, the GNU Assembler.
6*3d8817e4Smiod 
7*3d8817e4Smiod    GAS is free software; you can redistribute it and/or modify
8*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
9*3d8817e4Smiod    the Free Software Foundation; either version 2, or (at your option)
10*3d8817e4Smiod    any later version.
11*3d8817e4Smiod 
12*3d8817e4Smiod    GAS is distributed in the hope that it will be useful,
13*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*3d8817e4Smiod    GNU General Public License for more details.
16*3d8817e4Smiod 
17*3d8817e4Smiod    You should have received a copy of the GNU General Public License
18*3d8817e4Smiod    along with GAS; see the file COPYING.  If not, write to the Free
19*3d8817e4Smiod    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20*3d8817e4Smiod    02110-1301, USA.  */
21*3d8817e4Smiod 
22*3d8817e4Smiod #include <string.h>
23*3d8817e4Smiod 
24*3d8817e4Smiod #include "as.h"
25*3d8817e4Smiod #include "safe-ctype.h"
26*3d8817e4Smiod 
27*3d8817e4Smiod #ifndef FALSE
28*3d8817e4Smiod #define FALSE (0)
29*3d8817e4Smiod #endif
30*3d8817e4Smiod #ifndef TRUE
31*3d8817e4Smiod #define TRUE  (1)
32*3d8817e4Smiod #endif
33*3d8817e4Smiod 
34*3d8817e4Smiod #ifdef TRACE
35*3d8817e4Smiod static void flonum_print (const FLONUM_TYPE *);
36*3d8817e4Smiod #endif
37*3d8817e4Smiod 
38*3d8817e4Smiod #define ASSUME_DECIMAL_MARK_IS_DOT
39*3d8817e4Smiod 
40*3d8817e4Smiod /***********************************************************************\
41*3d8817e4Smiod  *									*
42*3d8817e4Smiod  *	Given a string of decimal digits , with optional decimal	*
43*3d8817e4Smiod  *	mark and optional decimal exponent (place value) of the		*
44*3d8817e4Smiod  *	lowest_order decimal digit: produce a floating point		*
45*3d8817e4Smiod  *	number. The number is 'generic' floating point: our		*
46*3d8817e4Smiod  *	caller will encode it for a specific machine architecture.	*
47*3d8817e4Smiod  *									*
48*3d8817e4Smiod  *	Assumptions							*
49*3d8817e4Smiod  *		uses base (radix) 2					*
50*3d8817e4Smiod  *		this machine uses 2's complement binary integers	*
51*3d8817e4Smiod  *		target flonums use "      "         "       "		*
52*3d8817e4Smiod  *		target flonums exponents fit in a long			*
53*3d8817e4Smiod  *									*
54*3d8817e4Smiod  \***********************************************************************/
55*3d8817e4Smiod 
56*3d8817e4Smiod /*
57*3d8817e4Smiod 
58*3d8817e4Smiod   Syntax:
59*3d8817e4Smiod 
60*3d8817e4Smiod   <flonum> ::= <optional-sign> <decimal-number> <optional-exponent>
61*3d8817e4Smiod   <optional-sign> ::= '+' | '-' | {empty}
62*3d8817e4Smiod   <decimal-number> ::= <integer>
63*3d8817e4Smiod   | <integer> <radix-character>
64*3d8817e4Smiod   | <integer> <radix-character> <integer>
65*3d8817e4Smiod   | <radix-character> <integer>
66*3d8817e4Smiod 
67*3d8817e4Smiod   <optional-exponent> ::= {empty}
68*3d8817e4Smiod   | <exponent-character> <optional-sign> <integer>
69*3d8817e4Smiod 
70*3d8817e4Smiod   <integer> ::= <digit> | <digit> <integer>
71*3d8817e4Smiod   <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
72*3d8817e4Smiod   <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"}
73*3d8817e4Smiod   <radix-character> ::= {one character from "string_of_decimal_marks"}
74*3d8817e4Smiod 
75*3d8817e4Smiod   */
76*3d8817e4Smiod 
77*3d8817e4Smiod int
atof_generic(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)78*3d8817e4Smiod atof_generic (/* return pointer to just AFTER number we read.  */
79*3d8817e4Smiod 	      char **address_of_string_pointer,
80*3d8817e4Smiod 	      /* At most one per number.  */
81*3d8817e4Smiod 	      const char *string_of_decimal_marks,
82*3d8817e4Smiod 	      const char *string_of_decimal_exponent_marks,
83*3d8817e4Smiod 	      FLONUM_TYPE *address_of_generic_floating_point_number)
84*3d8817e4Smiod {
85*3d8817e4Smiod   int return_value;		/* 0 means OK.  */
86*3d8817e4Smiod   char *first_digit;
87*3d8817e4Smiod   unsigned int number_of_digits_before_decimal;
88*3d8817e4Smiod   unsigned int number_of_digits_after_decimal;
89*3d8817e4Smiod   long decimal_exponent;
90*3d8817e4Smiod   unsigned int number_of_digits_available;
91*3d8817e4Smiod   char digits_sign_char;
92*3d8817e4Smiod 
93*3d8817e4Smiod   /*
94*3d8817e4Smiod    * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
95*3d8817e4Smiod    * It would be simpler to modify the string, but we don't; just to be nice
96*3d8817e4Smiod    * to caller.
97*3d8817e4Smiod    * We need to know how many digits we have, so we can allocate space for
98*3d8817e4Smiod    * the digits' value.
99*3d8817e4Smiod    */
100*3d8817e4Smiod 
101*3d8817e4Smiod   char *p;
102*3d8817e4Smiod   char c;
103*3d8817e4Smiod   int seen_significant_digit;
104*3d8817e4Smiod 
105*3d8817e4Smiod #ifdef ASSUME_DECIMAL_MARK_IS_DOT
106*3d8817e4Smiod   assert (string_of_decimal_marks[0] == '.'
107*3d8817e4Smiod 	  && string_of_decimal_marks[1] == 0);
108*3d8817e4Smiod #define IS_DECIMAL_MARK(c)	((c) == '.')
109*3d8817e4Smiod #else
110*3d8817e4Smiod #define IS_DECIMAL_MARK(c)	(0 != strchr (string_of_decimal_marks, (c)))
111*3d8817e4Smiod #endif
112*3d8817e4Smiod 
113*3d8817e4Smiod   first_digit = *address_of_string_pointer;
114*3d8817e4Smiod   c = *first_digit;
115*3d8817e4Smiod 
116*3d8817e4Smiod   if (c == '-' || c == '+')
117*3d8817e4Smiod     {
118*3d8817e4Smiod       digits_sign_char = c;
119*3d8817e4Smiod       first_digit++;
120*3d8817e4Smiod     }
121*3d8817e4Smiod   else
122*3d8817e4Smiod     digits_sign_char = '+';
123*3d8817e4Smiod 
124*3d8817e4Smiod   switch (first_digit[0])
125*3d8817e4Smiod     {
126*3d8817e4Smiod     case 'n':
127*3d8817e4Smiod     case 'N':
128*3d8817e4Smiod       if (!strncasecmp ("nan", first_digit, 3))
129*3d8817e4Smiod 	{
130*3d8817e4Smiod 	  address_of_generic_floating_point_number->sign = 0;
131*3d8817e4Smiod 	  address_of_generic_floating_point_number->exponent = 0;
132*3d8817e4Smiod 	  address_of_generic_floating_point_number->leader =
133*3d8817e4Smiod 	    address_of_generic_floating_point_number->low;
134*3d8817e4Smiod 	  *address_of_string_pointer = first_digit + 3;
135*3d8817e4Smiod 	  return 0;
136*3d8817e4Smiod 	}
137*3d8817e4Smiod       break;
138*3d8817e4Smiod 
139*3d8817e4Smiod     case 'i':
140*3d8817e4Smiod     case 'I':
141*3d8817e4Smiod       if (!strncasecmp ("inf", first_digit, 3))
142*3d8817e4Smiod 	{
143*3d8817e4Smiod 	  address_of_generic_floating_point_number->sign =
144*3d8817e4Smiod 	    digits_sign_char == '+' ? 'P' : 'N';
145*3d8817e4Smiod 	  address_of_generic_floating_point_number->exponent = 0;
146*3d8817e4Smiod 	  address_of_generic_floating_point_number->leader =
147*3d8817e4Smiod 	    address_of_generic_floating_point_number->low;
148*3d8817e4Smiod 
149*3d8817e4Smiod 	  first_digit += 3;
150*3d8817e4Smiod 	  if (!strncasecmp ("inity", first_digit, 5))
151*3d8817e4Smiod 	    first_digit += 5;
152*3d8817e4Smiod 
153*3d8817e4Smiod 	  *address_of_string_pointer = first_digit;
154*3d8817e4Smiod 
155*3d8817e4Smiod 	  return 0;
156*3d8817e4Smiod 	}
157*3d8817e4Smiod       break;
158*3d8817e4Smiod     }
159*3d8817e4Smiod 
160*3d8817e4Smiod   number_of_digits_before_decimal = 0;
161*3d8817e4Smiod   number_of_digits_after_decimal = 0;
162*3d8817e4Smiod   decimal_exponent = 0;
163*3d8817e4Smiod   seen_significant_digit = 0;
164*3d8817e4Smiod   for (p = first_digit;
165*3d8817e4Smiod        (((c = *p) != '\0')
166*3d8817e4Smiod 	&& (!c || !IS_DECIMAL_MARK (c))
167*3d8817e4Smiod 	&& (!c || !strchr (string_of_decimal_exponent_marks, c)));
168*3d8817e4Smiod        p++)
169*3d8817e4Smiod     {
170*3d8817e4Smiod       if (ISDIGIT (c))
171*3d8817e4Smiod 	{
172*3d8817e4Smiod 	  if (seen_significant_digit || c > '0')
173*3d8817e4Smiod 	    {
174*3d8817e4Smiod 	      ++number_of_digits_before_decimal;
175*3d8817e4Smiod 	      seen_significant_digit = 1;
176*3d8817e4Smiod 	    }
177*3d8817e4Smiod 	  else
178*3d8817e4Smiod 	    {
179*3d8817e4Smiod 	      first_digit++;
180*3d8817e4Smiod 	    }
181*3d8817e4Smiod 	}
182*3d8817e4Smiod       else
183*3d8817e4Smiod 	{
184*3d8817e4Smiod 	  break;		/* p -> char after pre-decimal digits.  */
185*3d8817e4Smiod 	}
186*3d8817e4Smiod     }				/* For each digit before decimal mark.  */
187*3d8817e4Smiod 
188*3d8817e4Smiod #ifndef OLD_FLOAT_READS
189*3d8817e4Smiod   /* Ignore trailing 0's after the decimal point.  The original code here
190*3d8817e4Smiod    * (ifdef'd out) does not do this, and numbers like
191*3d8817e4Smiod    *	4.29496729600000000000e+09	(2**31)
192*3d8817e4Smiod    * come out inexact for some reason related to length of the digit
193*3d8817e4Smiod    * string.
194*3d8817e4Smiod    */
195*3d8817e4Smiod   if (c && IS_DECIMAL_MARK (c))
196*3d8817e4Smiod     {
197*3d8817e4Smiod       unsigned int zeros = 0;	/* Length of current string of zeros */
198*3d8817e4Smiod 
199*3d8817e4Smiod       for (p++; (c = *p) && ISDIGIT (c); p++)
200*3d8817e4Smiod 	{
201*3d8817e4Smiod 	  if (c == '0')
202*3d8817e4Smiod 	    {
203*3d8817e4Smiod 	      zeros++;
204*3d8817e4Smiod 	    }
205*3d8817e4Smiod 	  else
206*3d8817e4Smiod 	    {
207*3d8817e4Smiod 	      number_of_digits_after_decimal += 1 + zeros;
208*3d8817e4Smiod 	      zeros = 0;
209*3d8817e4Smiod 	    }
210*3d8817e4Smiod 	}
211*3d8817e4Smiod     }
212*3d8817e4Smiod #else
213*3d8817e4Smiod   if (c && IS_DECIMAL_MARK (c))
214*3d8817e4Smiod     {
215*3d8817e4Smiod       for (p++;
216*3d8817e4Smiod 	   (((c = *p) != '\0')
217*3d8817e4Smiod 	    && (!c || !strchr (string_of_decimal_exponent_marks, c)));
218*3d8817e4Smiod 	   p++)
219*3d8817e4Smiod 	{
220*3d8817e4Smiod 	  if (ISDIGIT (c))
221*3d8817e4Smiod 	    {
222*3d8817e4Smiod 	      /* This may be retracted below.  */
223*3d8817e4Smiod 	      number_of_digits_after_decimal++;
224*3d8817e4Smiod 
225*3d8817e4Smiod 	      if ( /* seen_significant_digit || */ c > '0')
226*3d8817e4Smiod 		{
227*3d8817e4Smiod 		  seen_significant_digit = TRUE;
228*3d8817e4Smiod 		}
229*3d8817e4Smiod 	    }
230*3d8817e4Smiod 	  else
231*3d8817e4Smiod 	    {
232*3d8817e4Smiod 	      if (!seen_significant_digit)
233*3d8817e4Smiod 		{
234*3d8817e4Smiod 		  number_of_digits_after_decimal = 0;
235*3d8817e4Smiod 		}
236*3d8817e4Smiod 	      break;
237*3d8817e4Smiod 	    }
238*3d8817e4Smiod 	}			/* For each digit after decimal mark.  */
239*3d8817e4Smiod     }
240*3d8817e4Smiod 
241*3d8817e4Smiod   while (number_of_digits_after_decimal
242*3d8817e4Smiod 	 && first_digit[number_of_digits_before_decimal
243*3d8817e4Smiod 			+ number_of_digits_after_decimal] == '0')
244*3d8817e4Smiod     --number_of_digits_after_decimal;
245*3d8817e4Smiod #endif
246*3d8817e4Smiod 
247*3d8817e4Smiod   if (flag_m68k_mri)
248*3d8817e4Smiod     {
249*3d8817e4Smiod       while (c == '_')
250*3d8817e4Smiod 	c = *++p;
251*3d8817e4Smiod     }
252*3d8817e4Smiod   if (c && strchr (string_of_decimal_exponent_marks, c))
253*3d8817e4Smiod     {
254*3d8817e4Smiod       char digits_exponent_sign_char;
255*3d8817e4Smiod 
256*3d8817e4Smiod       c = *++p;
257*3d8817e4Smiod       if (flag_m68k_mri)
258*3d8817e4Smiod 	{
259*3d8817e4Smiod 	  while (c == '_')
260*3d8817e4Smiod 	    c = *++p;
261*3d8817e4Smiod 	}
262*3d8817e4Smiod       if (c && strchr ("+-", c))
263*3d8817e4Smiod 	{
264*3d8817e4Smiod 	  digits_exponent_sign_char = c;
265*3d8817e4Smiod 	  c = *++p;
266*3d8817e4Smiod 	}
267*3d8817e4Smiod       else
268*3d8817e4Smiod 	{
269*3d8817e4Smiod 	  digits_exponent_sign_char = '+';
270*3d8817e4Smiod 	}
271*3d8817e4Smiod 
272*3d8817e4Smiod       for (; (c); c = *++p)
273*3d8817e4Smiod 	{
274*3d8817e4Smiod 	  if (ISDIGIT (c))
275*3d8817e4Smiod 	    {
276*3d8817e4Smiod 	      decimal_exponent = decimal_exponent * 10 + c - '0';
277*3d8817e4Smiod 	      /*
278*3d8817e4Smiod 	       * BUG! If we overflow here, we lose!
279*3d8817e4Smiod 	       */
280*3d8817e4Smiod 	    }
281*3d8817e4Smiod 	  else
282*3d8817e4Smiod 	    {
283*3d8817e4Smiod 	      break;
284*3d8817e4Smiod 	    }
285*3d8817e4Smiod 	}
286*3d8817e4Smiod 
287*3d8817e4Smiod       if (digits_exponent_sign_char == '-')
288*3d8817e4Smiod 	{
289*3d8817e4Smiod 	  decimal_exponent = -decimal_exponent;
290*3d8817e4Smiod 	}
291*3d8817e4Smiod     }
292*3d8817e4Smiod 
293*3d8817e4Smiod   *address_of_string_pointer = p;
294*3d8817e4Smiod 
295*3d8817e4Smiod   number_of_digits_available =
296*3d8817e4Smiod     number_of_digits_before_decimal + number_of_digits_after_decimal;
297*3d8817e4Smiod   return_value = 0;
298*3d8817e4Smiod   if (number_of_digits_available == 0)
299*3d8817e4Smiod     {
300*3d8817e4Smiod       address_of_generic_floating_point_number->exponent = 0;	/* Not strictly necessary */
301*3d8817e4Smiod       address_of_generic_floating_point_number->leader
302*3d8817e4Smiod 	= -1 + address_of_generic_floating_point_number->low;
303*3d8817e4Smiod       address_of_generic_floating_point_number->sign = digits_sign_char;
304*3d8817e4Smiod       /* We have just concocted (+/-)0.0E0 */
305*3d8817e4Smiod 
306*3d8817e4Smiod     }
307*3d8817e4Smiod   else
308*3d8817e4Smiod     {
309*3d8817e4Smiod       int count;		/* Number of useful digits left to scan.  */
310*3d8817e4Smiod 
311*3d8817e4Smiod       LITTLENUM_TYPE *digits_binary_low;
312*3d8817e4Smiod       unsigned int precision;
313*3d8817e4Smiod       unsigned int maximum_useful_digits;
314*3d8817e4Smiod       unsigned int number_of_digits_to_use;
315*3d8817e4Smiod       unsigned int more_than_enough_bits_for_digits;
316*3d8817e4Smiod       unsigned int more_than_enough_littlenums_for_digits;
317*3d8817e4Smiod       unsigned int size_of_digits_in_littlenums;
318*3d8817e4Smiod       unsigned int size_of_digits_in_chars;
319*3d8817e4Smiod       FLONUM_TYPE power_of_10_flonum;
320*3d8817e4Smiod       FLONUM_TYPE digits_flonum;
321*3d8817e4Smiod 
322*3d8817e4Smiod       precision = (address_of_generic_floating_point_number->high
323*3d8817e4Smiod 		   - address_of_generic_floating_point_number->low
324*3d8817e4Smiod 		   + 1);	/* Number of destination littlenums.  */
325*3d8817e4Smiod 
326*3d8817e4Smiod       /* Includes guard bits (two littlenums worth) */
327*3d8817e4Smiod       maximum_useful_digits = (((precision - 2))
328*3d8817e4Smiod 			       * ( (LITTLENUM_NUMBER_OF_BITS))
329*3d8817e4Smiod 			       * 1000000 / 3321928)
330*3d8817e4Smiod 	+ 2;			/* 2 :: guard digits.  */
331*3d8817e4Smiod 
332*3d8817e4Smiod       if (number_of_digits_available > maximum_useful_digits)
333*3d8817e4Smiod 	{
334*3d8817e4Smiod 	  number_of_digits_to_use = maximum_useful_digits;
335*3d8817e4Smiod 	}
336*3d8817e4Smiod       else
337*3d8817e4Smiod 	{
338*3d8817e4Smiod 	  number_of_digits_to_use = number_of_digits_available;
339*3d8817e4Smiod 	}
340*3d8817e4Smiod 
341*3d8817e4Smiod       /* Cast these to SIGNED LONG first, otherwise, on systems with
342*3d8817e4Smiod 	 LONG wider than INT (such as Alpha OSF/1), unsignedness may
343*3d8817e4Smiod 	 cause unexpected results.  */
344*3d8817e4Smiod       decimal_exponent += ((long) number_of_digits_before_decimal
345*3d8817e4Smiod 			   - (long) number_of_digits_to_use);
346*3d8817e4Smiod 
347*3d8817e4Smiod       more_than_enough_bits_for_digits
348*3d8817e4Smiod 	= (number_of_digits_to_use * 3321928 / 1000000 + 1);
349*3d8817e4Smiod 
350*3d8817e4Smiod       more_than_enough_littlenums_for_digits
351*3d8817e4Smiod 	= (more_than_enough_bits_for_digits
352*3d8817e4Smiod 	   / LITTLENUM_NUMBER_OF_BITS)
353*3d8817e4Smiod 	+ 2;
354*3d8817e4Smiod 
355*3d8817e4Smiod       /* Compute (digits) part. In "12.34E56" this is the "1234" part.
356*3d8817e4Smiod 	 Arithmetic is exact here. If no digits are supplied then this
357*3d8817e4Smiod 	 part is a 0 valued binary integer.  Allocate room to build up
358*3d8817e4Smiod 	 the binary number as littlenums.  We want this memory to
359*3d8817e4Smiod 	 disappear when we leave this function.  Assume no alignment
360*3d8817e4Smiod 	 problems => (room for n objects) == n * (room for 1
361*3d8817e4Smiod 	 object).  */
362*3d8817e4Smiod 
363*3d8817e4Smiod       size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
364*3d8817e4Smiod       size_of_digits_in_chars = size_of_digits_in_littlenums
365*3d8817e4Smiod 	* sizeof (LITTLENUM_TYPE);
366*3d8817e4Smiod 
367*3d8817e4Smiod       digits_binary_low = (LITTLENUM_TYPE *)
368*3d8817e4Smiod 	alloca (size_of_digits_in_chars);
369*3d8817e4Smiod 
370*3d8817e4Smiod       memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);
371*3d8817e4Smiod 
372*3d8817e4Smiod       /* Digits_binary_low[] is allocated and zeroed.  */
373*3d8817e4Smiod 
374*3d8817e4Smiod       /*
375*3d8817e4Smiod        * Parse the decimal digits as if * digits_low was in the units position.
376*3d8817e4Smiod        * Emit a binary number into digits_binary_low[].
377*3d8817e4Smiod        *
378*3d8817e4Smiod        * Use a large-precision version of:
379*3d8817e4Smiod        * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
380*3d8817e4Smiod        */
381*3d8817e4Smiod 
382*3d8817e4Smiod       for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
383*3d8817e4Smiod 	{
384*3d8817e4Smiod 	  c = *p;
385*3d8817e4Smiod 	  if (ISDIGIT (c))
386*3d8817e4Smiod 	    {
387*3d8817e4Smiod 	      /*
388*3d8817e4Smiod 	       * Multiply by 10. Assume can never overflow.
389*3d8817e4Smiod 	       * Add this digit to digits_binary_low[].
390*3d8817e4Smiod 	       */
391*3d8817e4Smiod 
392*3d8817e4Smiod 	      long carry;
393*3d8817e4Smiod 	      LITTLENUM_TYPE *littlenum_pointer;
394*3d8817e4Smiod 	      LITTLENUM_TYPE *littlenum_limit;
395*3d8817e4Smiod 
396*3d8817e4Smiod 	      littlenum_limit = digits_binary_low
397*3d8817e4Smiod 		+ more_than_enough_littlenums_for_digits
398*3d8817e4Smiod 		- 1;
399*3d8817e4Smiod 
400*3d8817e4Smiod 	      carry = c - '0';	/* char -> binary */
401*3d8817e4Smiod 
402*3d8817e4Smiod 	      for (littlenum_pointer = digits_binary_low;
403*3d8817e4Smiod 		   littlenum_pointer <= littlenum_limit;
404*3d8817e4Smiod 		   littlenum_pointer++)
405*3d8817e4Smiod 		{
406*3d8817e4Smiod 		  long work;
407*3d8817e4Smiod 
408*3d8817e4Smiod 		  work = carry + 10 * (long) (*littlenum_pointer);
409*3d8817e4Smiod 		  *littlenum_pointer = work & LITTLENUM_MASK;
410*3d8817e4Smiod 		  carry = work >> LITTLENUM_NUMBER_OF_BITS;
411*3d8817e4Smiod 		}
412*3d8817e4Smiod 
413*3d8817e4Smiod 	      if (carry != 0)
414*3d8817e4Smiod 		{
415*3d8817e4Smiod 		  /*
416*3d8817e4Smiod 		   * We have a GROSS internal error.
417*3d8817e4Smiod 		   * This should never happen.
418*3d8817e4Smiod 		   */
419*3d8817e4Smiod 		  as_fatal (_("failed sanity check"));
420*3d8817e4Smiod 		}
421*3d8817e4Smiod 	    }
422*3d8817e4Smiod 	  else
423*3d8817e4Smiod 	    {
424*3d8817e4Smiod 	      ++count;		/* '.' doesn't alter digits used count.  */
425*3d8817e4Smiod 	    }
426*3d8817e4Smiod 	}
427*3d8817e4Smiod 
428*3d8817e4Smiod       /*
429*3d8817e4Smiod        * Digits_binary_low[] properly encodes the value of the digits.
430*3d8817e4Smiod        * Forget about any high-order littlenums that are 0.
431*3d8817e4Smiod        */
432*3d8817e4Smiod       while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0
433*3d8817e4Smiod 	     && size_of_digits_in_littlenums >= 2)
434*3d8817e4Smiod 	size_of_digits_in_littlenums--;
435*3d8817e4Smiod 
436*3d8817e4Smiod       digits_flonum.low = digits_binary_low;
437*3d8817e4Smiod       digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1;
438*3d8817e4Smiod       digits_flonum.leader = digits_flonum.high;
439*3d8817e4Smiod       digits_flonum.exponent = 0;
440*3d8817e4Smiod       /*
441*3d8817e4Smiod        * The value of digits_flonum . sign should not be important.
442*3d8817e4Smiod        * We have already decided the output's sign.
443*3d8817e4Smiod        * We trust that the sign won't influence the other parts of the number!
444*3d8817e4Smiod        * So we give it a value for these reasons:
445*3d8817e4Smiod        * (1) courtesy to humans reading/debugging
446*3d8817e4Smiod        *     these numbers so they don't get excited about strange values
447*3d8817e4Smiod        * (2) in future there may be more meaning attached to sign,
448*3d8817e4Smiod        *     and what was
449*3d8817e4Smiod        *     harmless noise may become disruptive, ill-conditioned (or worse)
450*3d8817e4Smiod        *     input.
451*3d8817e4Smiod        */
452*3d8817e4Smiod       digits_flonum.sign = '+';
453*3d8817e4Smiod 
454*3d8817e4Smiod       {
455*3d8817e4Smiod 	/*
456*3d8817e4Smiod 	 * Compute the mantssa (& exponent) of the power of 10.
457*3d8817e4Smiod 	 * If successful, then multiply the power of 10 by the digits
458*3d8817e4Smiod 	 * giving return_binary_mantissa and return_binary_exponent.
459*3d8817e4Smiod 	 */
460*3d8817e4Smiod 
461*3d8817e4Smiod 	LITTLENUM_TYPE *power_binary_low;
462*3d8817e4Smiod 	int decimal_exponent_is_negative;
463*3d8817e4Smiod 	/* This refers to the "-56" in "12.34E-56".  */
464*3d8817e4Smiod 	/* FALSE: decimal_exponent is positive (or 0) */
465*3d8817e4Smiod 	/* TRUE:  decimal_exponent is negative */
466*3d8817e4Smiod 	FLONUM_TYPE temporary_flonum;
467*3d8817e4Smiod 	LITTLENUM_TYPE *temporary_binary_low;
468*3d8817e4Smiod 	unsigned int size_of_power_in_littlenums;
469*3d8817e4Smiod 	unsigned int size_of_power_in_chars;
470*3d8817e4Smiod 
471*3d8817e4Smiod 	size_of_power_in_littlenums = precision;
472*3d8817e4Smiod 	/* Precision has a built-in fudge factor so we get a few guard bits.  */
473*3d8817e4Smiod 
474*3d8817e4Smiod 	decimal_exponent_is_negative = decimal_exponent < 0;
475*3d8817e4Smiod 	if (decimal_exponent_is_negative)
476*3d8817e4Smiod 	  {
477*3d8817e4Smiod 	    decimal_exponent = -decimal_exponent;
478*3d8817e4Smiod 	  }
479*3d8817e4Smiod 
480*3d8817e4Smiod 	/* From now on: the decimal exponent is > 0. Its sign is separate.  */
481*3d8817e4Smiod 
482*3d8817e4Smiod 	size_of_power_in_chars = size_of_power_in_littlenums
483*3d8817e4Smiod 	  * sizeof (LITTLENUM_TYPE) + 2;
484*3d8817e4Smiod 
485*3d8817e4Smiod 	power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
486*3d8817e4Smiod 	temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
487*3d8817e4Smiod 	memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
488*3d8817e4Smiod 	*power_binary_low = 1;
489*3d8817e4Smiod 	power_of_10_flonum.exponent = 0;
490*3d8817e4Smiod 	power_of_10_flonum.low = power_binary_low;
491*3d8817e4Smiod 	power_of_10_flonum.leader = power_binary_low;
492*3d8817e4Smiod 	power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1;
493*3d8817e4Smiod 	power_of_10_flonum.sign = '+';
494*3d8817e4Smiod 	temporary_flonum.low = temporary_binary_low;
495*3d8817e4Smiod 	temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1;
496*3d8817e4Smiod 	/*
497*3d8817e4Smiod 	 * (power) == 1.
498*3d8817e4Smiod 	 * Space for temporary_flonum allocated.
499*3d8817e4Smiod 	 */
500*3d8817e4Smiod 
501*3d8817e4Smiod 	/*
502*3d8817e4Smiod 	 * ...
503*3d8817e4Smiod 	 *
504*3d8817e4Smiod 	 * WHILE	more bits
505*3d8817e4Smiod 	 * DO	find next bit (with place value)
506*3d8817e4Smiod 	 *	multiply into power mantissa
507*3d8817e4Smiod 	 * OD
508*3d8817e4Smiod 	 */
509*3d8817e4Smiod 	{
510*3d8817e4Smiod 	  int place_number_limit;
511*3d8817e4Smiod 	  /* Any 10^(2^n) whose "n" exceeds this */
512*3d8817e4Smiod 	  /* value will fall off the end of */
513*3d8817e4Smiod 	  /* flonum_XXXX_powers_of_ten[].  */
514*3d8817e4Smiod 	  int place_number;
515*3d8817e4Smiod 	  const FLONUM_TYPE *multiplicand;	/* -> 10^(2^n) */
516*3d8817e4Smiod 
517*3d8817e4Smiod 	  place_number_limit = table_size_of_flonum_powers_of_ten;
518*3d8817e4Smiod 
519*3d8817e4Smiod 	  multiplicand = (decimal_exponent_is_negative
520*3d8817e4Smiod 			  ? flonum_negative_powers_of_ten
521*3d8817e4Smiod 			  : flonum_positive_powers_of_ten);
522*3d8817e4Smiod 
523*3d8817e4Smiod 	  for (place_number = 1;/* Place value of this bit of exponent.  */
524*3d8817e4Smiod 	       decimal_exponent;/* Quit when no more 1 bits in exponent.  */
525*3d8817e4Smiod 	       decimal_exponent >>= 1, place_number++)
526*3d8817e4Smiod 	    {
527*3d8817e4Smiod 	      if (decimal_exponent & 1)
528*3d8817e4Smiod 		{
529*3d8817e4Smiod 		  if (place_number > place_number_limit)
530*3d8817e4Smiod 		    {
531*3d8817e4Smiod 		      /* The decimal exponent has a magnitude so great
532*3d8817e4Smiod 			 that our tables can't help us fragment it.
533*3d8817e4Smiod 			 Although this routine is in error because it
534*3d8817e4Smiod 			 can't imagine a number that big, signal an
535*3d8817e4Smiod 			 error as if it is the user's fault for
536*3d8817e4Smiod 			 presenting such a big number.  */
537*3d8817e4Smiod 		      return_value = ERROR_EXPONENT_OVERFLOW;
538*3d8817e4Smiod 		      /* quit out of loop gracefully */
539*3d8817e4Smiod 		      decimal_exponent = 0;
540*3d8817e4Smiod 		    }
541*3d8817e4Smiod 		  else
542*3d8817e4Smiod 		    {
543*3d8817e4Smiod #ifdef TRACE
544*3d8817e4Smiod 		      printf ("before multiply, place_number = %d., power_of_10_flonum:\n",
545*3d8817e4Smiod 			      place_number);
546*3d8817e4Smiod 
547*3d8817e4Smiod 		      flonum_print (&power_of_10_flonum);
548*3d8817e4Smiod 		      (void) putchar ('\n');
549*3d8817e4Smiod #endif
550*3d8817e4Smiod #ifdef TRACE
551*3d8817e4Smiod 		      printf ("multiplier:\n");
552*3d8817e4Smiod 		      flonum_print (multiplicand + place_number);
553*3d8817e4Smiod 		      (void) putchar ('\n');
554*3d8817e4Smiod #endif
555*3d8817e4Smiod 		      flonum_multip (multiplicand + place_number,
556*3d8817e4Smiod 				     &power_of_10_flonum, &temporary_flonum);
557*3d8817e4Smiod #ifdef TRACE
558*3d8817e4Smiod 		      printf ("after multiply:\n");
559*3d8817e4Smiod 		      flonum_print (&temporary_flonum);
560*3d8817e4Smiod 		      (void) putchar ('\n');
561*3d8817e4Smiod #endif
562*3d8817e4Smiod 		      flonum_copy (&temporary_flonum, &power_of_10_flonum);
563*3d8817e4Smiod #ifdef TRACE
564*3d8817e4Smiod 		      printf ("after copy:\n");
565*3d8817e4Smiod 		      flonum_print (&power_of_10_flonum);
566*3d8817e4Smiod 		      (void) putchar ('\n');
567*3d8817e4Smiod #endif
568*3d8817e4Smiod 		    } /* If this bit of decimal_exponent was computable.*/
569*3d8817e4Smiod 		} /* If this bit of decimal_exponent was set.  */
570*3d8817e4Smiod 	    } /* For each bit of binary representation of exponent */
571*3d8817e4Smiod #ifdef TRACE
572*3d8817e4Smiod 	  printf ("after computing power_of_10_flonum:\n");
573*3d8817e4Smiod 	  flonum_print (&power_of_10_flonum);
574*3d8817e4Smiod 	  (void) putchar ('\n');
575*3d8817e4Smiod #endif
576*3d8817e4Smiod 	}
577*3d8817e4Smiod 
578*3d8817e4Smiod       }
579*3d8817e4Smiod 
580*3d8817e4Smiod       /*
581*3d8817e4Smiod        * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
582*3d8817e4Smiod        * It may be the number 1, in which case we don't NEED to multiply.
583*3d8817e4Smiod        *
584*3d8817e4Smiod        * Multiply (decimal digits) by power_of_10_flonum.
585*3d8817e4Smiod        */
586*3d8817e4Smiod 
587*3d8817e4Smiod       flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
588*3d8817e4Smiod       /* Assert sign of the number we made is '+'.  */
589*3d8817e4Smiod       address_of_generic_floating_point_number->sign = digits_sign_char;
590*3d8817e4Smiod 
591*3d8817e4Smiod     }
592*3d8817e4Smiod   return return_value;
593*3d8817e4Smiod }
594*3d8817e4Smiod 
595*3d8817e4Smiod #ifdef TRACE
596*3d8817e4Smiod static void
flonum_print(f)597*3d8817e4Smiod flonum_print (f)
598*3d8817e4Smiod      const FLONUM_TYPE *f;
599*3d8817e4Smiod {
600*3d8817e4Smiod   LITTLENUM_TYPE *lp;
601*3d8817e4Smiod   char littlenum_format[10];
602*3d8817e4Smiod   sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2);
603*3d8817e4Smiod #define print_littlenum(LP)	(printf (littlenum_format, LP))
604*3d8817e4Smiod   printf ("flonum @%p %c e%ld", f, f->sign, f->exponent);
605*3d8817e4Smiod   if (f->low < f->high)
606*3d8817e4Smiod     for (lp = f->high; lp >= f->low; lp--)
607*3d8817e4Smiod       print_littlenum (*lp);
608*3d8817e4Smiod   else
609*3d8817e4Smiod     for (lp = f->low; lp <= f->high; lp++)
610*3d8817e4Smiod       print_littlenum (*lp);
611*3d8817e4Smiod   printf ("\n");
612*3d8817e4Smiod   fflush (stdout);
613*3d8817e4Smiod }
614*3d8817e4Smiod #endif
615*3d8817e4Smiod 
616*3d8817e4Smiod /* end of atof_generic.c */
617