emacs-devel
[Top][All Lists]
Advanced

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

Re: macro FIXNUM_OVERFLOW_P in lisp.h is valid ?


From: Toru TSUNEYOSHI
Subject: Re: macro FIXNUM_OVERFLOW_P in lisp.h is valid ?
Date: Sun, 25 Oct 2009 03:45:39 +0900

Thanks for your checking.

From: Eli Zaretskii <address@hidden>

> OK, but please make your patch compare against MOST_POSITIVE_FIXNUM,
> instead of using INT_MAX or LONG_MAX.  Also, if you know that the
> value does not overflow an EMACS_INT, you can simply call make_number,
> instead of make_fixnum_or_float.

I revised the patch as you wrote.
Would you like to check it?

;; supplement
;; check list (with results on 32-bit platforms)

(string-to-number "268435455")          ; 2^28 - 1
=>                 268435455
(string-to-number "268435456")          ; 2^28
=>                 268435456.0
(string-to-number "268435457")          ; 2^28 + 1
=>                 268435457.0
(string-to-number "-268435456")         ; - 2^28
=>                 -268435456
(string-to-number "-268435457")         ; - 2^28 - 1
=>                 -268435457.0
(string-to-number "536870911")          ; 2^29 - 1
=>                 536870911.0
(string-to-number "1073741822")         ; 2^30 - 1
=>                 1073741822.0
(string-to-number "2147483647")         ; 2^31 - 1
=>                 2147483647.0
(string-to-number "1152921504606846975") ; 2^60 - 1
=>                1.1529215046068467e+018
(string-to-number "1152921504606846976") ; 2^60
=>                1.1529215046068467e+018
(string-to-number "1152921504606846977") ; 2^60 + 1
=>                1.1529215046068467e+018
(string-to-number "-1152921504606846976") ; - 2^60
=>                -1.1529215046068467e+018
(string-to-number "-1152921504606846977") ; - 2^60 - 1
=>                -1.1529215046068467e+018
(string-to-number "9223372036854775807") ; 2^63 - 1
=>                9.223372036854778e+018
--- data.c.orig 2009-06-21 13:38:14.000000000 +0900
+++ data.c      2009-10-25 03:35:54.414697700 +0900
@@ -2392,17 +2392,43 @@
     val = make_float (sign * atof (p));
   else
     {
-      double v = 0;
+      unsigned char *old_p = p;
+      EMACS_INT most_fixnum, chknum, v = 0;
+      int overflow = 0;                /* most_fixnum overflow */
 
-      while (1)
+      most_fixnum = sign > 0 ? MOST_POSITIVE_FIXNUM : MOST_NEGATIVE_FIXNUM * 
-1;
+      chknum = most_fixnum / b;
+
+      while (v >= 0)
        {
          int digit = digit_to_number (*p++, b);
          if (digit < 0)
            break;
+         if (chknum < v / b)
+           {
+             overflow = 1;
+             break;
+           }
          v = v * b + digit;
        }
 
-      val = make_fixnum_or_float (sign * v);
+      if (!overflow && v <= most_fixnum && v >= 0)
+       val = make_number (sign * v);
+      else
+       {
+         double w = 0;
+         p = old_p;
+
+         while (1)
+           {
+             int digit = digit_to_number (*p++, b);
+             if (digit < 0)
+               break;
+             w = w * b + digit;
+           }
+
+         val = make_float (sign * w);
+       }
     }
 
   return val;

reply via email to

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