/* atof_generic.c - turn a string of digits into a Flonum
- Copyright (C) 1987-2019 Free Software Foundation, Inc.
+ Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#ifndef OLD_FLOAT_READS
/* Ignore trailing 0's after the decimal point. The original code here
- * (ifdef'd out) does not do this, and numbers like
- * 4.29496729600000000000e+09 (2**31)
- * come out inexact for some reason related to length of the digit
- * string.
- */
+ (ifdef'd out) does not do this, and numbers like
+ 4.29496729600000000000e+09 (2**31)
+ come out inexact for some reason related to length of the digit
+ string. */
+
+ /* The case number_of_digits_before_decimal = 0 is handled for
+ deleting zeros after decimal. In this case the decimal mark and
+ the first zero digits after decimal mark are skipped. */
+ seen_significant_digit = 0;
+ signed long subtract_decimal_exponent = 0;
+
if (c && IS_DECIMAL_MARK (c))
{
- unsigned int zeros = 0; /* Length of current string of zeros */
+ unsigned int zeros = 0; /* Length of current string of zeros. */
+
+ if (number_of_digits_before_decimal == 0)
+ /* Skip decimal mark. */
+ first_digit++;
for (p++; (c = *p) && ISDIGIT (c); p++)
{
if (c == '0')
{
- zeros++;
+ if (number_of_digits_before_decimal == 0
+ && !seen_significant_digit)
+ {
+ /* Skip '0' and the decimal mark. */
+ first_digit++;
+ subtract_decimal_exponent--;
+ }
+ else
+ zeros++;
}
else
{
+ seen_significant_digit = 1;
number_of_digits_after_decimal += 1 + zeros;
zeros = 0;
}
}
}
+#ifndef OLD_FLOAT_READS
+ /* Subtract_decimal_exponent != 0 when number_of_digits_before_decimal = 0
+ and first digit after decimal is '0'. */
+ decimal_exponent += subtract_decimal_exponent;
+#endif
+
*address_of_string_pointer = p;
number_of_digits_available =
- address_of_generic_floating_point_number->low
+ 1); /* Number of destination littlenums. */
- /* Includes guard bits (two littlenums worth) */
- maximum_useful_digits = (((precision - 2))
- * ( (LITTLENUM_NUMBER_OF_BITS))
- * 1000000 / 3321928)
- + 2; /* 2 :: guard digits. */
+ /* precision includes two littlenums worth of guard bits,
+ so this gives us 10 decimal guard digits here. */
+ maximum_useful_digits = (precision
+ * LITTLENUM_NUMBER_OF_BITS
+ * 1000000 / 3321928
+ + 1); /* round up. */
if (number_of_digits_available > maximum_useful_digits)
{