+
+ /* Check for hex float. */
+ if (*s == '0' && c_tolower (s[1]) == 'x'
+ && (c_isxdigit (s[2]) || ('.' == s[2] && c_isxdigit (s[3]))))
+ {
+ hex = true;
+ s += 2;
+ for (;; ++s)
+ {
+ if (c_isxdigit (*s))
+ {
+ got_digit = true;
+
+ /* Make sure that multiplication by 16 will not overflow. */
+ if (num > DBL_MAX / 16)
+ /* The value of the digit doesn't matter, since we have already
+ gotten as many digits as can be represented in a `double'.
+ This doesn't necessarily mean the result will overflow.
+ The exponent may reduce it to within range.
+
+ We just need to record that there was another
+ digit so that we can multiply by 16 later. */
+ ++exponent;
+ else
+ num = ((num * 16.0)
+ + (c_tolower (*s) - (c_isdigit (*s) ? '0' : 'a' - 10)));
+
+ /* Keep track of the number of digits after the decimal point.
+ If we just divided by 16 here, we would lose precision. */
+ if (got_dot)
+ --exponent;
+ }
+ else if (!got_dot && *s == '.')
+ /* Record that we have found the decimal point. */
+ got_dot = true;
+ else
+ /* Any other character terminates the number. */
+ break;
+ }
+ }
+
+ /* Not a hex float. */
+ else