comparison 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
comparison
equal deleted inserted replaced
5735:ff13c44ce0d9 5736:3192994c49ca
103 # define bignum_to_emacs_int(b) bignum_to_long(b) 103 # define bignum_to_emacs_int(b) bignum_to_long(b)
104 #elif SIZEOF_EMACS_INT == SIZEOF_INT 104 #elif SIZEOF_EMACS_INT == SIZEOF_INT
105 # define bignum_fits_emacs_int_p(b) bignum_fits_int_p(b) 105 # define bignum_fits_emacs_int_p(b) bignum_fits_int_p(b)
106 # define bignum_to_emacs_int(b) bignum_to_int(b) 106 # define bignum_to_emacs_int(b) bignum_to_int(b)
107 #else 107 #else
108 # error Bignums currently do not work with long long Emacs integers. 108 # define bignum_fits_emacs_int_p(b) bignum_fits_llong_p(b)
109 # define bignum_to_emacs_int(b) bignum_to_llong(b)
109 #endif 110 #endif
110 111
111 extern Lisp_Object make_bignum (long); 112 extern Lisp_Object make_bignum (long);
113 extern Lisp_Object make_bignum_un (unsigned long);
114 extern Lisp_Object make_bignum_ll (long long);
115 extern Lisp_Object make_bignum_ull (unsigned long long);
112 extern Lisp_Object make_bignum_bg (bignum); 116 extern Lisp_Object make_bignum_bg (bignum);
113 extern bignum scratch_bignum, scratch_bignum2; 117 extern bignum scratch_bignum, scratch_bignum2;
114 118
115 #else /* !HAVE_BIGNUM */ 119 #else /* !HAVE_BIGNUM */
116 120
117 #define BIGNUMP(x) 0 121 #define BIGNUMP(x) 0
118 #define CHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x) 122 #define CHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x)
119 #define CONCHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x) 123 #define CONCHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x)
120 typedef void bignum; 124 typedef void bignum;
121 #define make_bignum(l) This XEmacs does not support bignums 125 #define make_bignum(l) This XEmacs does not support bignums
126 #define make_bignum_ll(l) This XEmacs does not support bignums
122 #define make_bignum_bg(b) This XEmacs does not support bignums 127 #define make_bignum_bg(b) This XEmacs does not support bignums
123 128
124 #endif /* HAVE_BIGNUM */ 129 #endif /* HAVE_BIGNUM */
125 130
126 extern Lisp_Object Qbignump; 131 extern Lisp_Object Qbignump;
138 if (!INTEGERP (x)) \ 143 if (!INTEGERP (x)) \
139 x = wrong_type_argument (Qintegerp, x); \ 144 x = wrong_type_argument (Qintegerp, x); \
140 } while (0) 145 } while (0)
141 146
142 #ifdef HAVE_BIGNUM 147 #ifdef HAVE_BIGNUM
143 #define make_integer(x) \ 148 #define make_integer(x) \
144 (NUMBER_FITS_IN_A_FIXNUM (x) ? make_fixnum (x) : make_bignum (x)) 149 (NUMBER_FITS_IN_A_FIXNUM (x) ? make_fixnum (x) \
150 : (sizeof (x) > SIZEOF_LONG ? make_bignum_ll (x) : make_bignum (x)))
151 #define make_unsigned_integer(x) \
152 (UNSIGNED_NUMBER_FITS_IN_A_FIXNUM (x) ? make_fixnum (x) \
153 : (sizeof (x) > SIZEOF_LONG ? make_bignum_ull (x) : make_bignum_un (x)))
145 #else 154 #else
146 #define make_integer(x) make_fixnum (x) 155 #define make_integer(x) make_fixnum (x)
156 #define make_unsigned_integer(x) make_fixnum ((EMACS_INT) x)
147 #endif 157 #endif
148 158
149 extern Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum; 159 extern Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum;
150 EXFUN (Fintegerp, 1); 160 EXFUN (Fintegerp, 1);
151 EXFUN (Fevenp, 1); 161 EXFUN (Fevenp, 1);
168 reasonable to call this macro and the associated Lisp function 178 reasonable to call this macro and the associated Lisp function
169 NATNUMP. */ 179 NATNUMP. */
170 180
171 #ifdef HAVE_BIGNUM 181 #ifdef HAVE_BIGNUM
172 #define NATNUMP(x) ((FIXNUMP (x) && XFIXNUM (x) >= 0) || \ 182 #define NATNUMP(x) ((FIXNUMP (x) && XFIXNUM (x) >= 0) || \
173 (BIGNUMP (x) && bignum_sign (XBIGNUM_DATA (x)) >= 0)) 183 (BIGNUMP (x) && bignum_sign (XBIGNUM_DATA (x)) >= 0))
174 #else 184 #else
175 #define NATNUMP(x) (FIXNUMP (x) && XFIXNUM (x) >= 0) 185 #define NATNUMP(x) (FIXNUMP (x) && XFIXNUM (x) >= 0)
176 #endif 186 #endif
177 187
178 #define CHECK_NATNUM(x) do { \ 188 #define CHECK_NATNUM(x) do { \
374 non_fixnum_number_p (Lisp_Object object)) 384 non_fixnum_number_p (Lisp_Object object))
375 { 385 {
376 if (LRECORDP (object)) 386 if (LRECORDP (object))
377 { 387 {
378 switch (XRECORD_LHEADER (object)->type) 388 switch (XRECORD_LHEADER (object)->type)
379 { 389 {
380 case lrecord_type_float: 390 case lrecord_type_float:
381 #ifdef HAVE_BIGNUM 391 #ifdef HAVE_BIGNUM
382 case lrecord_type_bignum: 392 case lrecord_type_bignum:
383 #endif 393 #endif
384 #ifdef HAVE_RATIO 394 #ifdef HAVE_RATIO
385 case lrecord_type_ratio: 395 case lrecord_type_ratio:
386 #endif 396 #endif
387 #ifdef HAVE_BIGFLOAT 397 #ifdef HAVE_BIGFLOAT
388 case lrecord_type_bigfloat: 398 case lrecord_type_bigfloat:
389 #endif 399 #endif
390 return 1; 400 return 1;
391 } 401 }
392 } 402 }
393 return 0; 403 return 0;
394 } 404 }
395 #define NON_FIXNUM_NUMBER_P(X) non_fixnum_number_p (X) 405 #define NON_FIXNUM_NUMBER_P(X) non_fixnum_number_p (X)
396 406