unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum))
@ 2009-12-03 14:36 Helmut Eller
  2009-12-03 20:52 ` Stefan Monnier
  2011-09-18  9:47 ` Lars Magne Ingebrigtsen
  0 siblings, 2 replies; 8+ messages in thread
From: Helmut Eller @ 2009-12-03 14:36 UTC (permalink / raw)
  To: emacs-pretest-bug


(setq x (string-to-number (number-to-string most-positive-fixnum)))
(= most-positive-fixnum x) => nil
   
x is 2305843009213693440 but it should be most-positive-fixnum
which is 2305843009213693951.

The test
(= most-positive-fixnum 
   (string-to-number (number-to-string most-positive-fixnum)))
seems to work as expected on 32-bit machines but not so on 64 bit.

Helmut.

In GNU Emacs 23.1.50.1 (x86_64-unknown-linux-gnu)
 of 2009-12-03
configured using `configure  '--without-x''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: nil
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum))
  2009-12-03 14:36 bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum)) Helmut Eller
@ 2009-12-03 20:52 ` Stefan Monnier
  2009-12-05 12:36   ` Helmut Eller
  2011-09-18  9:47 ` Lars Magne Ingebrigtsen
  1 sibling, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2009-12-03 20:52 UTC (permalink / raw)
  To: Helmut Eller; +Cc: 5114

> (setq x (string-to-number (number-to-string most-positive-fixnum)))
> (= most-positive-fixnum x) => nil
   
> x is 2305843009213693440 but it should be most-positive-fixnum
> which is 2305843009213693951.

> The test
> (= most-positive-fixnum 
>    (string-to-number (number-to-string most-positive-fixnum)))
> seems to work as expected on 32-bit machines but not so on 64 bit.

Indeed, it passes through a floating point conversion, so there's only
abour 52 bit of precesion.


        Stefan





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum))
  2009-12-03 20:52 ` Stefan Monnier
@ 2009-12-05 12:36   ` Helmut Eller
  2009-12-05 14:25     ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Helmut Eller @ 2009-12-05 12:36 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 5114

[-- Attachment #1: Type: text/plain, Size: 614 bytes --]

* Stefan Monnier [2009-12-03 21:52+0100] writes:

>> (setq x (string-to-number (number-to-string most-positive-fixnum)))
>> (= most-positive-fixnum x) => nil
>    
>> x is 2305843009213693440 but it should be most-positive-fixnum
>> which is 2305843009213693951.
>
>> The test
>> (= most-positive-fixnum 
>>    (string-to-number (number-to-string most-positive-fixnum)))
>> seems to work as expected on 32-bit machines but not so on 64 bit.
>
> Indeed, it passes through a floating point conversion, so there's only
> abour 52 bit of precesion.

Here is a patch for string-to-number to use the full fixnum range:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: string-to-number.patch --]
[-- Type: text/x-diff, Size: 962 bytes --]

--- data.c.~1.308.~	2009-12-05 08:07:48.000000000 +0100
+++ data.c	2009-12-05 13:27:33.000000000 +0100
@@ -2393,23 +2393,26 @@
     p++;
 
   if (isfloat_string (p, 1) && b == 10)
-    val = make_float (sign * atof (p));
-  else
-    {
-      double v = 0;
-
-      while (1)
-	{
-	  int digit = digit_to_number (*p++, b);
-	  if (digit < 0)
-	    break;
-	  v = v * b + digit;
-	}
-
-      val = make_fixnum_or_float (sign * v);
-    }
-
-  return val;
+    return make_float (sign * atof (p));
+  else {
+    unsigned long u = 0;
+    while (1)
+      {
+	int digit = digit_to_number (*p++, b);
+	if (digit < 0)
+	  return make_number (sign * u);
+	else if (u <= (MOST_POSITIVE_FIXNUM - digit) / b)
+	  u = u * b + digit;
+	else
+	  {
+	    /* overflow to flonums */
+	    double f = ((double)u) * b + digit;
+	    while (digit = digit_to_number (*p++, b), digit >= 0)
+	      f = f * b + digit;
+	    return make_float (sign * f);
+	  }
+      }
+  }
 }
 
 \f

[-- Attachment #3: Type: text/plain, Size: 8 bytes --]


Helmut

^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum))
  2009-12-05 12:36   ` Helmut Eller
@ 2009-12-05 14:25     ` Eli Zaretskii
  2009-12-05 15:18       ` Helmut Eller
  0 siblings, 1 reply; 8+ messages in thread
From: Eli Zaretskii @ 2009-12-05 14:25 UTC (permalink / raw)
  To: Helmut Eller, 5114; +Cc: monnier

> From: Helmut Eller <eller.helmut@gmail.com>
> Date: Sat, 05 Dec 2009 13:36:41 +0100
> Cc: 5114@emacsbugs.donarmstrong.com
> 
> +  else {
> +    unsigned long u = 0;

This assumes that `unsigned long' is the same width as EMACS_INT.
This could be false, e.g., with 64-bit MS-Windows.  Isn't it better to
use EMACS_INT instead?





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum))
  2009-12-05 14:25     ` Eli Zaretskii
@ 2009-12-05 15:18       ` Helmut Eller
  2009-12-05 16:44         ` Eli Zaretskii
  0 siblings, 1 reply; 8+ messages in thread
From: Helmut Eller @ 2009-12-05 15:18 UTC (permalink / raw)
  To: bug-gnu-emacs

* Eli Zaretskii [2009-12-05 15:25+0100] writes:

>> From: Helmut Eller <eller.helmut@gmail.com>
>> Date: Sat, 05 Dec 2009 13:36:41 +0100
>> Cc: 5114@emacsbugs.donarmstrong.com
>> 
>> +  else {
>> +    unsigned long u = 0;
>
> This assumes that `unsigned long' is the same width as EMACS_INT.
> This could be false, e.g., with 64-bit MS-Windows.  Isn't it better to
> use EMACS_INT instead?

Using EMACS_UINT wouldn't hurt.  Does MOST_POSITIVE_FIXNUM not fit in a
unsigned long on Windows?  I assumed that longs are supposed to be as
wide as pointers.

Helmut







^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum))
  2009-12-05 15:18       ` Helmut Eller
@ 2009-12-05 16:44         ` Eli Zaretskii
  0 siblings, 0 replies; 8+ messages in thread
From: Eli Zaretskii @ 2009-12-05 16:44 UTC (permalink / raw)
  To: Helmut Eller, 5114

> From: Helmut Eller <eller.helmut@gmail.com>
> Date: Sat, 05 Dec 2009 16:18:13 +0100
> Cc: 
> 
> * Eli Zaretskii [2009-12-05 15:25+0100] writes:
> 
> >> From: Helmut Eller <eller.helmut@gmail.com>
> >> Date: Sat, 05 Dec 2009 13:36:41 +0100
> >> Cc: 5114@emacsbugs.donarmstrong.com
> >> 
> >> +  else {
> >> +    unsigned long u = 0;
> >
> > This assumes that `unsigned long' is the same width as EMACS_INT.
> > This could be false, e.g., with 64-bit MS-Windows.  Isn't it better to
> > use EMACS_INT instead?
> 
> Using EMACS_UINT wouldn't hurt.  Does MOST_POSITIVE_FIXNUM not fit in a
> unsigned long on Windows?

In the 32-bit Windows build, it does.  In the 64-bit Windows build
(which does not yet exist, since we don't yet support it), it will
not, because MS in their infinite wisdom (probably because backward
compatibility considerations wrt existing source code and headers)
decided to use the LLP64 programming model.

> I assumed that longs are supposed to be as wide as pointers.

Not on 64-bit Windows, they don't.





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum))
  2009-12-03 14:36 bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum)) Helmut Eller
  2009-12-03 20:52 ` Stefan Monnier
@ 2011-09-18  9:47 ` Lars Magne Ingebrigtsen
  2011-09-18 10:57   ` Leo
  1 sibling, 1 reply; 8+ messages in thread
From: Lars Magne Ingebrigtsen @ 2011-09-18  9:47 UTC (permalink / raw)
  To: Helmut Eller; +Cc: 5114

Helmut Eller <eller.helmut@gmail.com> writes:

> (setq x (string-to-number (number-to-string most-positive-fixnum)))
> (= most-positive-fixnum x) => nil
>
> x is 2305843009213693440 but it should be most-positive-fixnum
> which is 2305843009213693951.
>
> The test
> (= most-positive-fixnum 
>    (string-to-number (number-to-string most-positive-fixnum)))
> seems to work as expected on 32-bit machines but not so on 64 bit.

I'm unable to reproduce this on Emacs 24, so I think it's likely that
this has been fixed by all the numerical fixes that have been applied
the last year.

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum))
  2011-09-18  9:47 ` Lars Magne Ingebrigtsen
@ 2011-09-18 10:57   ` Leo
  0 siblings, 0 replies; 8+ messages in thread
From: Leo @ 2011-09-18 10:57 UTC (permalink / raw)
  To: Lars Magne Ingebrigtsen; +Cc: 5114, Helmut Eller

On 2011-09-18 17:47 +0800, Lars Magne Ingebrigtsen wrote:
> I'm unable to reproduce this on Emacs 24, so I think it's likely that
> this has been fixed by all the numerical fixes that have been applied
> the last year.

Indeed fixed in 24.x but present in emacs-23.

Leo





^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-09-18 10:57 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-03 14:36 bug#5114: 23.1.50; (string-to-number (number-to-string most-positive-fixnum)) Helmut Eller
2009-12-03 20:52 ` Stefan Monnier
2009-12-05 12:36   ` Helmut Eller
2009-12-05 14:25     ` Eli Zaretskii
2009-12-05 15:18       ` Helmut Eller
2009-12-05 16:44         ` Eli Zaretskii
2011-09-18  9:47 ` Lars Magne Ingebrigtsen
2011-09-18 10:57   ` Leo

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).