Mercurial > hg > xemacs-beta
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 |