diff src/number.h @ 5736:3192994c49ca

Convert C (un)signed long long values to bignums properly. This patch also does the following: - Uses make_fixnum instead of make_integer when the argument is guaranteed to be in the fixnum range. - Introduces make_unsigned_integer so that we handle unsigned values with the high bit set correctly. - Introduces conversions between bignums and (un)signed long long values. - Uses mp_set_memory_functions with the BSD MP code, if it exists. - Eliminates some unnecessary consing in the Lisp + and * implementations. - Fixes a problem with check_valid_xbm_inline(). This function is called during intialization. It calls Ftimes. When using pdump, this is a problem, because (a) the bignum code is not initialized until *after* dumping, so we don't try to dump any bignums, and (b) multiplication of integers is done inside bignums so we handle fixnum overflow correctly. I decided that an XBM file with dimensions that don't fit into fixnums is probably not something we want to try to handle anyway, and did the arithmetic with C values instead of Lisp values. Doing that broke one test, which started getting a different error message from the one it expected, so I adjusted the test to match the new reality. - Fixes a few miscellaneous bugs in the BSD MP code. See <CAHCOHQk0u0=eD1fUMHTNWi2Yh=1WgiYyCXdMbsGzHBNhdqYz4w@mail.gmail.com> in xemacs-patches, as well as followup messages.
author Jerry James <james@xemacs.org>
date Mon, 17 Jun 2013 10:23:00 -0600
parents 56144c8593a8
children a2912073be85
line wrap: on
line diff
--- a/src/number.h	Wed Apr 24 20:16:14 2013 -0400
+++ b/src/number.h	Mon Jun 17 10:23:00 2013 -0600
@@ -105,10 +105,14 @@
 # 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.
+# define bignum_fits_emacs_int_p(b) bignum_fits_llong_p(b)
+# define bignum_to_emacs_int(b) bignum_to_llong(b)
 #endif
 
 extern Lisp_Object make_bignum (long);
+extern Lisp_Object make_bignum_un (unsigned long);
+extern Lisp_Object make_bignum_ll (long long);
+extern Lisp_Object make_bignum_ull (unsigned long long);
 extern Lisp_Object make_bignum_bg (bignum);
 extern bignum scratch_bignum, scratch_bignum2;
 
@@ -119,6 +123,7 @@
 #define CONCHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x)
 typedef void bignum;
 #define make_bignum(l)     This XEmacs does not support bignums
+#define make_bignum_ll(l)  This XEmacs does not support bignums
 #define make_bignum_bg(b)  This XEmacs does not support bignums
 
 #endif /* HAVE_BIGNUM */
@@ -140,10 +145,15 @@
 }  while (0)
 
 #ifdef HAVE_BIGNUM
-#define make_integer(x) \
-  (NUMBER_FITS_IN_A_FIXNUM (x) ? make_fixnum (x) : make_bignum (x))
+#define make_integer(x)							\
+  (NUMBER_FITS_IN_A_FIXNUM (x) ? make_fixnum (x)			\
+   : (sizeof (x) > SIZEOF_LONG ? make_bignum_ll (x) : make_bignum (x)))
+#define make_unsigned_integer(x)					\
+  (UNSIGNED_NUMBER_FITS_IN_A_FIXNUM (x) ? make_fixnum (x)		\
+   : (sizeof (x) > SIZEOF_LONG ? make_bignum_ull (x) : make_bignum_un (x)))
 #else
 #define make_integer(x) make_fixnum (x)
+#define make_unsigned_integer(x) make_fixnum ((EMACS_INT) x)
 #endif
 
 extern Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum;
@@ -170,7 +180,7 @@
 
 #ifdef HAVE_BIGNUM
 #define NATNUMP(x) ((FIXNUMP (x) && XFIXNUM (x) >= 0) || \
-                    (BIGNUMP (x) && bignum_sign (XBIGNUM_DATA (x)) >= 0))
+		    (BIGNUMP (x) && bignum_sign (XBIGNUM_DATA (x)) >= 0))
 #else
 #define NATNUMP(x) (FIXNUMP (x) && XFIXNUM (x) >= 0)
 #endif
@@ -376,19 +386,19 @@
   if (LRECORDP (object))
     {
       switch (XRECORD_LHEADER (object)->type)
-        {
-        case lrecord_type_float:
+	{
+	case lrecord_type_float:
 #ifdef HAVE_BIGNUM
-        case lrecord_type_bignum:
+	case lrecord_type_bignum:
 #endif
 #ifdef HAVE_RATIO
-        case lrecord_type_ratio:
+	case lrecord_type_ratio:
 #endif
 #ifdef HAVE_BIGFLOAT
-        case lrecord_type_bigfloat:
+	case lrecord_type_bigfloat:
 #endif
-          return 1;
-        }
+	  return 1;
+	}
     }
   return 0;
 }