1 /* atof_generic.c - turn a string of digits into a Flonum
2 Copyright (C) 1987, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* static const char rcsid[] = "$Id$"; */
28 #define alloca __builtin_alloca
36 #define bzero(s,n) memset(s,0,n)
39 /* #define FALSE (0) */
40 /* #define TRUE (1) */
42 /***********************************************************************\
44 * Given a string of decimal digits , with optional decimal *
45 * mark and optional decimal exponent (place value) of the *
46 * lowest_order decimal digit: produce a floating point *
47 * number. The number is 'generic' floating point: our *
48 * caller will encode it for a specific machine architecture. *
51 * uses base (radix) 2 *
52 * this machine uses 2's complement binary integers *
53 * target flonums use " " " " *
54 * target flonums exponents fit in a long *
56 \***********************************************************************/
62 <flonum> ::= <optional-sign> <decimal-number> <optional-exponent>
63 <optional-sign> ::= '+' | '-' | {empty}
64 <decimal-number> ::= <integer>
65 | <integer> <radix-character>
66 | <integer> <radix-character> <integer>
67 | <radix-character> <integer>
68 <optional-exponent> ::= {empty} | <exponent-character> <optional-sign> <integer>
69 <integer> ::= <digit> | <digit> <integer>
70 <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
71 <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"}
72 <radix-character> ::= {one character from "string_of_decimal_marks"}
78 address_of_string_pointer, /* return pointer to just AFTER number we read. */
79 string_of_decimal_marks, /* At most one per number. */
80 string_of_decimal_exponent_marks,
81 address_of_generic_floating_point_number)
83 char * * address_of_string_pointer;
84 const char * string_of_decimal_marks;
85 const char * string_of_decimal_exponent_marks;
86 FLONUM_TYPE * address_of_generic_floating_point_number;
90 int return_value; /* 0 means OK. */
92 /* char * last_digit; JF unused */
93 int number_of_digits_before_decimal;
94 int number_of_digits_after_decimal;
95 long decimal_exponent;
96 int number_of_digits_available;
97 char digits_sign_char;
101 * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
102 * It would be simpler to modify the string, but we don't; just to be nice
104 * We need to know how many digits we have, so we can allocate space for
110 int seen_significant_digit;
112 first_digit = * address_of_string_pointer;
114 if (c=='-' || c=='+')
116 digits_sign_char = c;
120 digits_sign_char = '+';
122 if( (first_digit[0]=='n' || first_digit[0]=='N')
123 && (first_digit[1]=='a' || first_digit[1]=='A')
124 && (first_digit[2]=='n' || first_digit[2]=='N')) {
125 address_of_generic_floating_point_number->sign=0;
126 address_of_generic_floating_point_number->exponent=0;
127 address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low;
128 (*address_of_string_pointer)=first_digit+3;
131 if( (first_digit[0]=='i' || first_digit[0]=='I')
132 && (first_digit[1]=='n' || first_digit[1]=='N')
133 && (first_digit[2]=='f' || first_digit[2]=='F')) {
134 address_of_generic_floating_point_number->sign= digits_sign_char=='+' ? 'P' : 'N';
135 address_of_generic_floating_point_number->exponent=0;
136 address_of_generic_floating_point_number->leader=address_of_generic_floating_point_number->low;
137 if( (first_digit[3]=='i' || first_digit[3]=='I')
138 && (first_digit[4]=='n' || first_digit[4]=='N')
139 && (first_digit[5]=='i' || first_digit[5]=='I')
140 && (first_digit[6]=='t' || first_digit[6]=='T')
141 && (first_digit[7]=='y' || first_digit[7]=='Y'))
142 (*address_of_string_pointer)=first_digit+8;
144 (*address_of_string_pointer)=first_digit+3;
148 number_of_digits_before_decimal = 0;
149 number_of_digits_after_decimal = 0;
150 decimal_exponent = 0;
151 seen_significant_digit = 0;
152 for (p = first_digit;
154 && (!c || ! strchr (string_of_decimal_marks, c) )
155 && (!c || ! strchr (string_of_decimal_exponent_marks, c) );
160 if (seen_significant_digit || c > '0')
162 number_of_digits_before_decimal ++;
163 seen_significant_digit = 1;
172 break; /* p -> char after pre-decimal digits. */
174 } /* For each digit before decimal mark. */
176 #ifndef OLD_FLOAT_READS
177 /* Ignore trailing 0's after the decimal point. The original code here
178 * (ifdef'd out) does not do this, and numbers like
179 * 4.29496729600000000000e+09 (2**31)
180 * come out inexact for some reason related to length of the digit
183 if ( c && strchr(string_of_decimal_marks,c) ){
184 int zeros = 0; /* Length of current string of zeros */
186 for ( p++; (c = *p) && isdigit(c); p++ ){
190 number_of_digits_after_decimal += 1 + zeros;
196 if (c && strchr (string_of_decimal_marks, c))
200 && (!c || ! strchr (string_of_decimal_exponent_marks, c) );
205 number_of_digits_after_decimal ++; /* This may be retracted below. */
206 if (/* seen_significant_digit || */ c > '0')
208 seen_significant_digit = TRUE;
213 if ( ! seen_significant_digit)
215 number_of_digits_after_decimal = 0;
219 } /* For each digit after decimal mark. */
221 while(number_of_digits_after_decimal && first_digit[number_of_digits_before_decimal+number_of_digits_after_decimal]=='0')
222 --number_of_digits_after_decimal;
223 /* last_digit = p; JF unused */
226 if (c && strchr (string_of_decimal_exponent_marks, c) )
228 char digits_exponent_sign_char;
231 if (c && strchr ("+-",c))
233 digits_exponent_sign_char = c;
238 digits_exponent_sign_char = '+';
246 decimal_exponent = decimal_exponent * 10 + c - '0';
248 * BUG! If we overflow here, we lose!
256 if (digits_exponent_sign_char == '-')
258 decimal_exponent = - decimal_exponent;
261 * address_of_string_pointer = p;
264 number_of_digits_available =
265 number_of_digits_before_decimal
266 + number_of_digits_after_decimal;
268 if (number_of_digits_available == 0)
270 address_of_generic_floating_point_number -> exponent = 0; /* Not strictly necessary */
271 address_of_generic_floating_point_number -> leader
272 = -1 + address_of_generic_floating_point_number -> low;
273 address_of_generic_floating_point_number -> sign = digits_sign_char;
274 /* We have just concocted (+/-)0.0E0 */
278 LITTLENUM_TYPE * digits_binary_low;
280 int maximum_useful_digits;
281 int number_of_digits_to_use;
282 int more_than_enough_bits_for_digits;
283 int more_than_enough_littlenums_for_digits;
284 int size_of_digits_in_littlenums;
285 int size_of_digits_in_chars;
286 FLONUM_TYPE power_of_10_flonum;
287 FLONUM_TYPE digits_flonum;
290 precision = (address_of_generic_floating_point_number -> high
291 - address_of_generic_floating_point_number -> low
293 ); /* Number of destination littlenums. */
294 /* Includes guard bits (two littlenums worth) */
295 maximum_useful_digits = ( ((double) (precision - 2))
296 * ((double) (LITTLENUM_NUMBER_OF_BITS))
297 / (LOG_TO_BASE_2_OF_10)
299 + 2; /* 2 :: guard digits. */
300 if (number_of_digits_available > maximum_useful_digits)
302 number_of_digits_to_use = maximum_useful_digits;
306 number_of_digits_to_use = number_of_digits_available;
308 decimal_exponent += number_of_digits_before_decimal - number_of_digits_to_use;
310 more_than_enough_bits_for_digits
311 = ((((double)number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1);
312 more_than_enough_littlenums_for_digits
313 = ( more_than_enough_bits_for_digits
314 / LITTLENUM_NUMBER_OF_BITS
319 * Compute (digits) part. In "12.34E56" this is the "1234" part.
320 * Arithmetic is exact here. If no digits are supplied then
321 * this part is a 0 valued binary integer.
322 * Allocate room to build up the binary number as littlenums.
323 * We want this memory to disappear when we leave this function.
324 * Assume no alignment problems => (room for n objects) ==
325 * n * (room for 1 object).
328 size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
329 size_of_digits_in_chars = size_of_digits_in_littlenums
330 * sizeof( LITTLENUM_TYPE );
331 digits_binary_low = (LITTLENUM_TYPE *)
332 alloca (size_of_digits_in_chars);
333 bzero ((char *)digits_binary_low, size_of_digits_in_chars);
335 /* Digits_binary_low[] is allocated and zeroed. */
339 * Parse the decimal digits as if * digits_low was in the units position.
340 * Emit a binary number into digits_binary_low[].
342 * Use a large-precision version of:
343 * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
348 int count; /* Number of useful digits left to scan. */
350 for (p = first_digit, count = number_of_digits_to_use;
358 * Multiply by 10. Assume can never overflow.
359 * Add this digit to digits_binary_low[].
363 LITTLENUM_TYPE * littlenum_pointer;
364 LITTLENUM_TYPE * littlenum_limit;
368 + more_than_enough_littlenums_for_digits
370 carry = c - '0'; /* char -> binary */
371 for (littlenum_pointer = digits_binary_low;
372 littlenum_pointer <= littlenum_limit;
373 littlenum_pointer ++)
377 work = carry + 10 * (long)(*littlenum_pointer);
378 * littlenum_pointer = work & LITTLENUM_MASK;
379 carry = work >> LITTLENUM_NUMBER_OF_BITS;
384 * We have a GROSS internal error.
385 * This should never happen.
387 abort(); /* RMS prefers abort() to any message. */
392 ++ count; /* '.' doesn't alter digits used count. */
393 } /* if valid digit */
394 } /* for each digit */
398 * Digits_binary_low[] properly encodes the value of the digits.
399 * Forget about any high-order littlenums that are 0.
401 while (digits_binary_low [size_of_digits_in_littlenums - 1] == 0
402 && size_of_digits_in_littlenums >= 2)
403 size_of_digits_in_littlenums --;
405 digits_flonum . low = digits_binary_low;
406 digits_flonum . high = digits_binary_low + size_of_digits_in_littlenums - 1;
407 digits_flonum . leader = digits_flonum . high;
408 digits_flonum . exponent = 0;
410 * The value of digits_flonum . sign should not be important.
411 * We have already decided the output's sign.
412 * We trust that the sign won't influence the other parts of the number!
413 * So we give it a value for these reasons:
414 * (1) courtesy to humans reading/debugging
415 * these numbers so they don't get excited about strange values
416 * (2) in future there may be more meaning attached to sign,
418 * harmless noise may become disruptive, ill-conditioned (or worse)
421 digits_flonum . sign = '+';
425 * Compute the mantssa (& exponent) of the power of 10.
426 * If sucessful, then multiply the power of 10 by the digits
427 * giving return_binary_mantissa and return_binary_exponent.
430 LITTLENUM_TYPE *power_binary_low;
431 int decimal_exponent_is_negative;
432 /* This refers to the "-56" in "12.34E-56". */
433 /* FALSE: decimal_exponent is positive (or 0) */
434 /* TRUE: decimal_exponent is negative */
435 FLONUM_TYPE temporary_flonum;
436 LITTLENUM_TYPE *temporary_binary_low;
437 int size_of_power_in_littlenums;
438 int size_of_power_in_chars;
440 size_of_power_in_littlenums = precision;
441 /* Precision has a built-in fudge factor so we get a few guard bits. */
444 decimal_exponent_is_negative = decimal_exponent < 0;
445 if (decimal_exponent_is_negative)
447 decimal_exponent = - decimal_exponent;
449 /* From now on: the decimal exponent is > 0. Its sign is seperate. */
451 size_of_power_in_chars
452 = size_of_power_in_littlenums
453 * sizeof( LITTLENUM_TYPE ) + 2;
454 power_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars );
455 temporary_binary_low = (LITTLENUM_TYPE *) alloca ( size_of_power_in_chars );
456 bzero ((char *)power_binary_low, size_of_power_in_chars);
457 * power_binary_low = 1;
458 power_of_10_flonum . exponent = 0;
459 power_of_10_flonum . low = power_binary_low;
460 power_of_10_flonum . leader = power_binary_low;
461 power_of_10_flonum . high = power_binary_low + size_of_power_in_littlenums - 1;
462 power_of_10_flonum . sign = '+';
463 temporary_flonum . low = temporary_binary_low;
464 temporary_flonum . high = temporary_binary_low + size_of_power_in_littlenums - 1;
467 * Space for temporary_flonum allocated.
474 * DO find next bit (with place value)
475 * multiply into power mantissa
479 int place_number_limit;
480 /* Any 10^(2^n) whose "n" exceeds this */
481 /* value will fall off the end of */
482 /* flonum_XXXX_powers_of_ten[]. */
484 const FLONUM_TYPE * multiplicand; /* -> 10^(2^n) */
486 place_number_limit = table_size_of_flonum_powers_of_ten;
488 = ( decimal_exponent_is_negative
489 ? flonum_negative_powers_of_ten
490 : flonum_positive_powers_of_ten);
491 for (place_number = 1; /* Place value of this bit of exponent. */
492 decimal_exponent; /* Quit when no more 1 bits in exponent. */
493 decimal_exponent >>= 1
496 if (decimal_exponent & 1)
498 if (place_number > place_number_limit)
501 * The decimal exponent has a magnitude so great that
502 * our tables can't help us fragment it. Although this
503 * routine is in error because it can't imagine a
504 * number that big, signal an error as if it is the
505 * user's fault for presenting such a big number.
507 return_value = ERROR_EXPONENT_OVERFLOW;
509 * quit out of loop gracefully
511 decimal_exponent = 0;
516 printf("before multiply, place_number = %d., power_of_10_flonum:\n", place_number);
517 flonum_print( & power_of_10_flonum );
520 flonum_multip(multiplicand + place_number, &power_of_10_flonum, &temporary_flonum);
521 flonum_copy (& temporary_flonum, & power_of_10_flonum);
522 } /* If this bit of decimal_exponent was computable.*/
523 } /* If this bit of decimal_exponent was set. */
524 } /* For each bit of binary representation of exponent */
526 printf( " after computing power_of_10_flonum: " );
527 flonum_print( & power_of_10_flonum );
535 * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
536 * It may be the number 1, in which case we don't NEED to multiply.
538 * Multiply (decimal digits) by power_of_10_flonum.
541 flonum_multip (& power_of_10_flonum, & digits_flonum, address_of_generic_floating_point_number);
542 /* Assert sign of the number we made is '+'. */
543 address_of_generic_floating_point_number -> sign = digits_sign_char;
545 } /* If we had any significant digits. */
546 return (return_value);
547 } /* atof_generic () */
549 /* end: atof_generic.c */