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: Sat, 24 Oct 2009 16:46:55 +0900

>> So in 64-bit platforms, casting `double' to `int' causes lack of
>> precision already (because a double does not have 64 bits in the
>> mantissa), doesn't it?
> 
> So I make a patch for keep the precision.
> It tries to deal with the number in type `int' possibly, otherwise it
> deals with the number in type `double'.
> 
> Would you like to check it ?

I revised the patch.
--- data.c.original     2009-06-21 13:38:14.000000000 +0900
+++ data.c      2009-10-24 16:32:17.805194400 +0900
@@ -22,6 +22,7 @@
 #include <config.h>
 #include <signal.h>
 #include <stdio.h>
+#include <limits.h>
 #include "lisp.h"
 #include "puresize.h"
 #include "character.h"
@@ -2392,17 +2393,46 @@
     val = make_float (sign * atof (p));
   else
     {
-      double v = 0;
+      unsigned char *old_p = p;
+      EMACS_INT v = 0;
+      int overflow = 0;
 
-      while (1)
+      while (v >= 0)
        {
          int digit = digit_to_number (*p++, b);
          if (digit < 0)
            break;
+#ifdef _LP64
+         if (v > LONG_MAX / b)
+#else
+         if (v > INT_MAX / b)
+#endif
+           {
+             overflow = 1;
+             break;
+           }
          v = v * b + digit;
        }
 
-      val = make_fixnum_or_float (sign * v);
+      if (!overflow && v >= 0)
+       {
+         val = make_fixnum_or_float (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_fixnum_or_float (sign * w);
+       }
     }
 
   return val;

reply via email to

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