--- data.c.orig 2009-06-21 13:38:14.000000000 +0900 +++ data.c 2009-10-25 03:35:54.414697700 +0900 @@ -2392,17 +2392,43 @@ val = make_float (sign * atof (p)); else { - double v = 0; + unsigned char *old_p = p; + EMACS_INT most_fixnum, chknum, v = 0; + int overflow = 0; /* most_fixnum overflow */ - while (1) + most_fixnum = sign > 0 ? MOST_POSITIVE_FIXNUM : MOST_NEGATIVE_FIXNUM * -1; + chknum = most_fixnum / b; + + while (v >= 0) { int digit = digit_to_number (*p++, b); if (digit < 0) break; + if (chknum < v / b) + { + overflow = 1; + break; + } v = v * b + digit; } - val = make_fixnum_or_float (sign * v); + if (!overflow && v <= most_fixnum && v >= 0) + val = make_number (sign * v); + else + { + double w = 0; + p = old_p; + + while (1) + { + int digit = digit_to_number (*p++, b); + if (digit < 0) + break; + w = w * b + digit; + } + + val = make_float (sign * w); + } } return val;