Subject: bug#30408: closed (Re: Checking for loss of information on integer conversion)

From: [email-masked] (GNU bug Tracking System)
Date: Thu, 29 Mar 2018 18:10:01 +0000

Your bug report

#30408: 24.5; (format "%x" large-number) produces incorrect results

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
30408: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=30408
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: Checking for loss of information on integer conversion
From: Paul Eggert <[email-masked]>
To: Eli Zaretskii <[email-masked]>
Cc: [email-masked], David Sitsky <[email-masked]>
Date: Thu, 29 Mar 2018 11:09:45 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

On 03/29/2018 04:11 AM, Eli Zaretskii wrote:
> I'd suggest, for a good measure, to have a variable which would force
> the conversion to floats, avoiding an error even without the trailing
> period.  We can later remove that variable, or make it a no-op, if the
> danger of breaking existing code turns out low or non-existent.

OK, I did that, by installing the attached into master, after installing 
the proposed patch.

As a result, unless the user sets the new variable 
read-integer-overflow-as-float, the Lisp reader now rejects the program 
(format "%x" 2738188573457603759) by signaling an overflow error. As 
this was the basis of the original bug report, I'm marking the bug as done.

>From c213f465ba8038ce93314b96fd53ec3e35d34609 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Thu, 29 Mar 2018 11:01:38 -0700
Subject: [PATCH] New experimental variable read-integer-overflow-as-float.

Following a suggestion by Eli Zaretskii (Bug#30408#46).
* etc/NEWS: Mention it.
* src/lread.c (syms_of_lread): Add it.
(read1): Treat out-of-range integers as floats if
read-integer-overflow-as-float is non-nil.
---
 etc/NEWS    |  6 ++++--
 src/lread.c | 11 ++++++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 9161f2bd32..9dddc90213 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -356,8 +356,10 @@ implementation to format (Bug#30408).
 ** The Lisp reader now signals an overflow for plain decimal integers
 that do not end in '.' and are outside Emacs range.  Formerly the Lisp
 reader silently converted them to floating-point numbers, and signaled
-overflow only for integers with a radix that are outside machine range
-(Bug#30408).
+overflow only for integers with a radix that are outside machine range.
+To get the old behavior, set the new, experimental variable
+read-integer-overflow-as-float to t and please email
[email-masked] if you need that.  (Bug#30408).
 
 ---
 ** Some functions and variables obsolete since Emacs 22 have been removed:
diff --git a/src/lread.c b/src/lread.c
index a774524ee4..8fb61f5633 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3502,7 +3502,9 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
 
 	if (!quoted && !uninterned_symbol)
 	  {
-	    Lisp_Object result = string_to_number (read_buffer, 10, 0);
+	    int flags = (read_integer_overflow_as_float
+			 ? S2N_OVERFLOW_TO_FLOAT : 0);
+	    Lisp_Object result = string_to_number (read_buffer, 10, flags);
 	    if (! NILP (result))
 	      return unbind_to (count, result);
 	  }
@@ -4830,6 +4832,13 @@ were read in.  */);
 	       doc: /* Non-nil means read recursive structures using #N= and #N# syntax.  */);
   Vread_circle = Qt;
 
+  DEFVAR_BOOL ("read-integer-overflow-as-float",
+	       read_integer_overflow_as_float,
+	       doc: /* Non-nil means `read' quietly treats an out-of-range integer as floating point.
+Nil (the default) means signal an overflow unless the integer ends in `.'.
+This variable is experimental; email [email-masked] if you need it.  */);
+  read_integer_overflow_as_float = false;
+
   DEFVAR_LISP ("load-path", Vload_path,
 	       doc: /* List of directories to search for files to load.
 Each element is a string (directory file name) or nil (meaning
-- 
2.14.3

Subject: 24.5; (format "%x" large-number) produces incorrect results
From: David Sitsky <[email-masked]>
To: [email-masked]
Date: Sat, 10 Feb 2018 17:22:53 +1100
List-Id: <debbugs-submit.debbugs.gnu.org>

I wrote this originally on
https://emacs.stackexchange.com/questions/38710/why-does-format-x-some-large-number-produces-incorrect-results
and a poster recommended I mention this here.

I wanted the hexadecimal string for a large integer such as below:

(format "%x" 2738188573457603759)

This returns 2600000000f95c00 which is incorrect, it should be
2600000000f95caf.

The value of most-positive-fixnum on my box is 0x1fffffffffffffff which is
less than the number I'm supplying above.

As a user I'm a bit baffled what is happening. The manual indicates
integers larger than this range are converted to a floating-point number
which is a concern for precision but I suspect this is what is biting me
here?

I should have known there was an issue with this number since normally I
evaluate them directly using eval-last-sexp and it didn't show the
octal/hex variants.. :)

I wonder why Emacs Lisp doesn't support bignums by default, so precision
would not be an issue?