PATCH 21.5
Bignums are broken on 64-bit platforms, and have been since they were
first introduced. The problem is a spot in the code where I assumed
that EMACS_INT == int.
Do we know of any platforms where EMACS_INT == long long? I'll have to
think on how to address that.
src/ChangeLog addition:
2006-05-08 Jerry James <james(a)xemacs.org>
* number.c (Fcanonicalize_number): Use EMACS_INT instead of int,
which fixes bignum arithmetic on 64-bit platforms.
* number.h (bignum_fits_emacs_int_p): New macro.
* number.h (bignum_to_emacs_int): New macro.
xemacs-21.5 source patch:
Diff command: cvs -q diff -uN
Files affected: src/number.h src/number.c
Index: src/number.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/number.c,v
retrieving revision 1.16
diff -d -u -r1.16 number.c
--- src/number.c 2005/10/25 11:16:26 1.16
+++ src/number.c 2006/05/08 22:02:35
@@ -408,9 +408,9 @@
number = make_bignum_bg (XRATIO_NUMERATOR (number));
#endif
#ifdef HAVE_BIGNUM
- if (BIGNUMP (number) && bignum_fits_int_p (XBIGNUM_DATA (number)))
+ if (BIGNUMP (number) && bignum_fits_emacs_int_p (XBIGNUM_DATA (number)))
{
- int n = bignum_to_int (XBIGNUM_DATA (number));
+ EMACS_INT n = bignum_to_emacs_int (XBIGNUM_DATA (number));
if (NUMBER_FITS_IN_AN_EMACS_INT (n))
number = make_int (n);
}
Index: src/number.h
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/number.h,v
retrieving revision 1.4
diff -d -u -r1.4 number.h
--- src/number.h 2004/05/21 20:56:32 1.4
+++ src/number.h 2006/05/08 22:02:35
@@ -100,6 +100,16 @@
return Fcanonicalize_number (retval); \
} while (0)
+#if SIZEOF_EMACS_INT == SIZEOF_LONG
+# define bignum_fits_emacs_int_p(b) bignum_fits_long_p(b)
+# define bignum_to_emacs_int(b) bignum_to_long(b)
+#elif SIZEOF_EMACS_INT == SIZEOF_INT
+# define bignum_fits_emacs_int_p(b) bignum_fits_int_p(b)
+# define bignum_to_emacs_int(b) bignum_to_int(b)
+#else
+# error Bignums currently do not work with long long Emacs integers.
+#endif
+
extern Lisp_Object make_bignum (long);
extern Lisp_Object make_bignum_bg (bignum);
extern bignum scratch_bignum, scratch_bignum2;
--
Jerry James, Assistant Professor james(a)xemacs.org
Computer Science Department
http://www.cs.usu.edu/~jerry/
Utah State University