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