emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master dfb0ba7: Support "%x" etc. formats on more floats


From: Paul Eggert
Subject: [Emacs-diffs] master dfb0ba7: Support "%x" etc. formats on more floats
Date: Tue, 23 Jul 2019 04:46:46 -0400 (EDT)

branch: master
commit dfb0ba79b5f41ca6fed25a03d2a5cd6996ec4753
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 doc/lispref/strings.texi  | 10 ++++------
 src/editfns.c             | 17 ++++++++++++-----
 test/src/editfns-tests.el | 23 ++++++++++++-----------
 3 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index 521f163..69d571f 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 8e0c0c4..1b33f39 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 69cca5d..a106080 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 ()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]