]> git.eshelyaron.com Git - emacs.git/commitdiff
Support "%x" etc. formats on more floats
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 23 Jul 2019 08:42:32 +0000 (01:42 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 23 Jul 2019 08:46:41 +0000 (01:46 -0700)
* 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
src/editfns.c
test/src/editfns-tests.el

index 521f163663d06999034ddf8528f863c7b24ba2b9..69d571fab8a147cd53892896ed27f123a03d86cf 100644 (file)
@@ -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.
index 8e0c0c451e6e3e2ca5cfeed0e28b1abcca8b64fa..1b33f3971106a61ce879b461a0e113137378d518 100644 (file)
@@ -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;
index 69cca5d2bddbb87bf84462724344bf3fdcfa69e1..a1060808f6699d80bf24a6aef7fdc5a58012fd8a 100644 (file)
   (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))))
     (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 ()