diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index 4c5f72126ed..d28e15869aa 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -237,7 +237,8 @@ precede the number and its exponent. For example, @samp{1500.0}, @samp{+15e2}, @samp{15.0e+2}, @samp{+1500000e-3}, and @samp{.15e4} are five ways of writing a floating-point number whose value is 1500. They are all equivalent. Like Common Lisp, Emacs Lisp requires at -least one digit after any decimal point in a floating-point number; +least one digit after a decimal point in a floating-point number that +does not have an exponent; @samp{1500.} is an integer, not a floating-point number. Emacs Lisp treats @code{-0.0} as numerically equal to ordinary zero diff --git a/src/lread.c b/src/lread.c index bca53a9a37a..0b33fd0f254 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3938,8 +3938,7 @@ string_to_number (char const *string, int base, ptrdiff_t *plen) bool signedp = negative | positive; cp += signedp; - enum { INTOVERFLOW = 1, LEAD_INT = 2, DOT_CHAR = 4, TRAIL_INT = 8, - E_EXP = 16 }; + enum { INTOVERFLOW = 1, LEAD_INT = 2, TRAIL_INT = 4, E_EXP = 16 }; int state = 0; int leading_digit = digit_to_number (*cp, base); uintmax_t n = leading_digit; @@ -3959,7 +3958,6 @@ string_to_number (char const *string, int base, ptrdiff_t *plen) char const *after_digits = cp; if (*cp == '.') { - state |= DOT_CHAR; cp++; } @@ -4008,8 +4006,10 @@ string_to_number (char const *string, int base, ptrdiff_t *plen) cp = ecp; } - float_syntax = ((state & (DOT_CHAR|TRAIL_INT)) == (DOT_CHAR|TRAIL_INT) - || (state & ~INTOVERFLOW) == (LEAD_INT|E_EXP)); + /* A float has digits after the dot or an exponent. + This excludes numbers like "1." which are lexed as integers. */ + float_syntax = ((state & TRAIL_INT) + || ((state & LEAD_INT) && (state & E_EXP))); } if (plen) diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el index f2a60bcf327..dac8f95bc4d 100644 --- a/test/src/lread-tests.el +++ b/test/src/lread-tests.el @@ -196,4 +196,71 @@ literals (Bug#20852)." (should-error (read-event "foo: ")) (should-error (read-char-exclusive "foo: ")))) +(ert-deftest lread-float () + (should (equal (read "13") 13)) + (should (equal (read "+13") 13)) + (should (equal (read "-13") -13)) + (should (equal (read "13.") 13)) + (should (equal (read "+13.") 13)) + (should (equal (read "-13.") -13)) + (should (equal (read "13.25") 13.25)) + (should (equal (read "+13.25") 13.25)) + (should (equal (read "-13.25") -13.25)) + (should (equal (read ".25") 0.25)) + (should (equal (read "+.25") 0.25)) + (should (equal (read "-.25") -0.25)) + (should (equal (read "13e4") 130000.0)) + (should (equal (read "+13e4") 130000.0)) + (should (equal (read "-13e4") -130000.0)) + (should (equal (read "13e+4") 130000.0)) + (should (equal (read "+13e+4") 130000.0)) + (should (equal (read "-13e+4") -130000.0)) + (should (equal (read "625e-4") 0.0625)) + (should (equal (read "+625e-4") 0.0625)) + (should (equal (read "-625e-4") -0.0625)) + (should (equal (read "1.25e2") 125.0)) + (should (equal (read "+1.25e2") 125.0)) + (should (equal (read "-1.25e2") -125.0)) + (should (equal (read "1.25e+2") 125.0)) + (should (equal (read "+1.25e+2") 125.0)) + (should (equal (read "-1.25e+2") -125.0)) + (should (equal (read "1.25e-1") 0.125)) + (should (equal (read "+1.25e-1") 0.125)) + (should (equal (read "-1.25e-1") -0.125)) + (should (equal (read "4.e3") 4000.0)) + (should (equal (read "+4.e3") 4000.0)) + (should (equal (read "-4.e3") -4000.0)) + (should (equal (read "4.e+3") 4000.0)) + (should (equal (read "+4.e+3") 4000.0)) + (should (equal (read "-4.e+3") -4000.0)) + (should (equal (read "5.e-1") 0.5)) + (should (equal (read "+5.e-1") 0.5)) + (should (equal (read "-5.e-1") -0.5)) + (should (equal (read "0") 0)) + (should (equal (read "+0") 0)) + (should (equal (read "-0") 0)) + (should (equal (read "0.") 0)) + (should (equal (read "+0.") 0)) + (should (equal (read "-0.") 0)) + (should (equal (read "0.0") 0.0)) + (should (equal (read "+0.0") 0.0)) + (should (equal (read "-0.0") -0.0)) + (should (equal (read "0e5") 0.0)) + (should (equal (read "+0e5") 0.0)) + (should (equal (read "-0e5") -0.0)) + (should (equal (read "0e-5") 0.0)) + (should (equal (read "+0e-5") 0.0)) + (should (equal (read "-0e-5") -0.0)) + (should (equal (read ".0e-5") 0.0)) + (should (equal (read "+.0e-5") 0.0)) + (should (equal (read "-.0e-5") -0.0)) + (should (equal (read "0.0e-5") 0.0)) + (should (equal (read "+0.0e-5") 0.0)) + (should (equal (read "-0.0e-5") -0.0)) + (should (equal (read "0.e-5") 0.0)) + (should (equal (read "+0.e-5") 0.0)) + (should (equal (read "-0.e-5") -0.0)) + ) + + ;;; lread-tests.el ends here