From: Paul Eggert Date: Tue, 23 Jul 2019 08:42:32 +0000 (-0700) Subject: Support "%x" etc. formats on more floats X-Git-Tag: emacs-27.0.90~1817^2~159 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=dfb0ba79b5f41ca6fed25a03d2a5cd6996ec4753;p=emacs.git Support "%x" etc. formats on more floats * doc/lispref/strings.texi (Formatting Strings): Document this. * src/editfns.c (styled_format): Support %o, %x, and %X on finite floats less than zero or greater than UINTMAX_MAX. * test/src/editfns-tests.el (format-%x-large-float) (read-large-integer, format-%o-negative-float): Adjust tests to match extended behavior. Rename the latter test from format-%o-invalid-float, since the float is no longer invalid. * test/src/editfns-tests.el (format-%x-large-float) (read-large-integer): Test this. --- diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 521f163663d..69d571fab8a 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -923,9 +923,8 @@ Functions}). Thus, strings are enclosed in @samp{"} characters, and @cindex integer to octal Replace the specification with the base-eight representation of an integer. Negative integers are formatted in a platform-dependent -way. The object can also be a nonnegative floating-point -number that is formatted as an integer, dropping any fraction, if the -integer does not exceed machine limits. +way. The object can also be a floating-point number that is formatted +as an integer, dropping any fraction. @item %d Replace the specification with the base-ten representation of a signed @@ -938,9 +937,8 @@ formatted as an integer, dropping any fraction. Replace the specification with the base-sixteen representation of an integer. Negative integers are formatted in a platform-dependent way. @samp{%x} uses lower case and @samp{%X} uses upper -case. The object can also be a nonnegative floating-point number that -is formatted as an integer, dropping any fraction, if the integer does -not exceed machine limits. +case. The object can also be a floating-point number that is +formatted as an integer, dropping any fraction. @item %c Replace the specification with the character which is the value given. diff --git a/src/editfns.c b/src/editfns.c index 8e0c0c451e6..1b33f397110 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3594,6 +3594,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) sprintf_bytes = prec != 0; } else if (BIGNUMP (arg)) + bignum_arg: { int base = ((conversion == 'd' || conversion == 'i') ? 10 : conversion == 'o' ? 8 : 16); @@ -3655,11 +3656,17 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) else { double d = XFLOAT_DATA (arg); - double uintmax = UINTMAX_MAX; - if (! (0 <= d && d < uintmax + 1)) - xsignal1 (Qoverflow_error, arg); - x = d; - negative = false; + double abs_d = fabs (d); + if (abs_d < UINTMAX_MAX + 1.0) + { + negative = d <= -1; + x = abs_d; + } + else + { + arg = double_to_integer (d); + goto bignum_arg; + } } p[0] = negative ? '-' : plus_flag ? '+' : ' '; bool signedp = negative | plus_flag | space_flag; diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index 69cca5d2bdd..a1060808f66 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el @@ -165,13 +165,9 @@ (should (string-equal (format "%d" -18446744073709551616.0) "-18446744073709551616"))) -;; Perhaps Emacs will be improved someday to return the correct -;; answer for positive numbers instead of overflowing; in -;; that case these tests will need to be changed. In the meantime make -;; sure Emacs is reporting the overflow correctly. (ert-deftest format-%x-large-float () - (should-error (format "%x" 18446744073709551616.0) - :type 'overflow-error)) + (should (string-equal (format "%x" 18446744073709551616.0) + "10000000000000000"))) (ert-deftest read-large-integer () (should (eq (type-of (read (format "%d0" most-negative-fixnum))) 'integer)) (should (eq (type-of (read (format "%+d" (* -8.0 most-negative-fixnum)))) @@ -188,11 +184,16 @@ (dolist (val (list most-negative-fixnum (1+ most-negative-fixnum) -1 0 1 (1- most-positive-fixnum) most-positive-fixnum)) - (should (eq val (read (format fmt val))))))) - -(ert-deftest format-%o-invalid-float () - (should-error (format "%o" -1e-37) - :type 'overflow-error)) + (should (eq val (read (format fmt val))))) + (dolist (val (list (1+ most-positive-fixnum) + (* 2 (1+ most-positive-fixnum)) + (* 4 (1+ most-positive-fixnum)) + (* 8 (1+ most-positive-fixnum)) + 18446744073709551616.0)) + (should (= val (read (format fmt val))))))) + +(ert-deftest format-%o-negative-float () + (should (string-equal (format "%o" -1e-37) "0"))) ;; Bug#31938 (ert-deftest format-%d-float ()