+ /* Given a normal decimal floating point number of the form
+
+ dddd.dddd[eE][+-]ddd
+
+ where the decimal point and exponent are optional, fill out the
+ structure D. Exponent is appropriate if the significand is
+ treated as an integer, and normalizedExponent if the significand
+ is taken to have the decimal point after a single leading
+ non-zero digit.
+
+ If the value is zero, V->firstSigDigit points to a non-digit, and
+ the return exponent is zero.
+ */
+ struct decimalInfo {
+ const char *firstSigDigit;
+ const char *lastSigDigit;
+ int exponent;
+ int normalizedExponent;
+ };
+
+ void
+ interpretDecimal(const char *p, decimalInfo *D)
+ {
+ const char *dot;
+
+ p = skipLeadingZeroesAndAnyDot (p, &dot);
+
+ D->firstSigDigit = p;
+ D->exponent = 0;
+ D->normalizedExponent = 0;
+
+ for (;;) {
+ if (*p == '.') {
+ assert(dot == 0);
+ dot = p++;
+ }
+ if (decDigitValue(*p) >= 10U)
+ break;
+ p++;
+ }
+
+ /* If number is all zerooes accept any exponent. */
+ if (p != D->firstSigDigit) {
+ if (*p == 'e' || *p == 'E')
+ D->exponent = readExponent(p + 1);
+
+ /* Implied decimal point? */
+ if (!dot)
+ dot = p;
+
+ /* Drop insignificant trailing zeroes. */
+ do
+ do
+ p--;
+ while (*p == '0');
+ while (*p == '.');
+
+ /* Adjust the exponents for any decimal point. */
+ D->exponent += (dot - p) - (dot > p);
+ D->normalizedExponent = (D->exponent + (p - D->firstSigDigit)
+ - (dot > D->firstSigDigit && dot < p));
+ }
+
+ D->lastSigDigit = p;
+ }
+