1983
+ − 1 /* Definitions of numeric types for XEmacs.
+ − 2 Copyright (C) 2004 Jerry James.
+ − 3
+ − 4 This file is part of XEmacs.
+ − 5
+ − 6 XEmacs is free software; you can redistribute it and/or modify it
+ − 7 under the terms of the GNU General Public License as published by the
+ − 8 Free Software Foundation; either version 2, or (at your option) any
+ − 9 later version.
+ − 10
+ − 11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 14 for more details.
+ − 15
+ − 16 You should have received a copy of the GNU General Public License
+ − 17 along with XEmacs; see the file COPYING. If not, write to
+ − 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 19 Boston, MA 02111-1307, USA. */
+ − 20
+ − 21 /* Synched up with: Not in FSF. */
+ − 22
+ − 23 #ifndef INCLUDED_number_h_
+ − 24 #define INCLUDED_number_h_
+ − 25
+ − 26 /* The following types are always defined in the same manner:
+ − 27 fixnum = whatever fits in the Lisp_Object type
+ − 28 integer = union (fixnum, bignum)
+ − 29 rational = union (integer, ratio)
+ − 30 float = C double
+ − 31 floating = union(float, bigfloat) Anybody got a better name?
+ − 32 real = union (rational, floating)
+ − 33 number = real (should be union(real, complex) but no complex yet)
+ − 34
+ − 35 It is up to the library-specific code to define the remaining types,
+ − 36 namely: bignum, ratio, and bigfloat. Not all of these types may be
+ − 37 available. The top-level configure script should define the symbols
+ − 38 HAVE_BIGNUM, HAVE_RATIO, and HAVE_BIGFLOAT to indicate which it provides.
+ − 39 If some type is not defined by the library, this is what happens:
+ − 40
+ − 41 - bignum: bignump(x) is false for all x; any attempt to create a bignum
+ − 42 causes an error to be raised.
+ − 43
+ − 44 - ratio: we define our own structure consisting of two Lisp_Objects, which
+ − 45 are presumed to be integers (i.e., either fixnums or bignums). We do our
+ − 46 own GCD calculation, which is bound to be slow, to keep the ratios
+ − 47 reduced to canonical form. (FIXME: Not yet implemented.)
+ − 48
+ − 49 - bigfloat: bigfloat(x) is false for all x; any attempt to create a
+ − 50 bigfloat causes an error to be raised.
+ − 51
+ − 52 We (provide) the following symbols, so that Lisp code has some hope of
+ − 53 using this correctly:
+ − 54
+ − 55 - (provide 'bignum) if HAVE_BIGNUM
+ − 56 - (provde 'ratio) if HAVE_RATIO
+ − 57 - (provide 'bigfloat) if HAVE_BIGFLOAT
+ − 58 */
+ − 59
+ − 60 /* Load the library definitions */
+ − 61 #ifdef WITH_GMP
+ − 62 #include "number-gmp.h"
+ − 63 #endif
+ − 64 #ifdef WITH_MP
+ − 65 #include "number-mp.h"
+ − 66 #endif
+ − 67
+ − 68
+ − 69 /********************************* Bignums **********************************/
+ − 70 #ifdef HAVE_BIGNUM
+ − 71
+ − 72 struct Lisp_Bignum
+ − 73 {
+ − 74 struct lrecord_header lheader;
+ − 75 bignum data;
+ − 76 };
+ − 77 typedef struct Lisp_Bignum Lisp_Bignum;
+ − 78
+ − 79 DECLARE_LRECORD (bignum, Lisp_Bignum);
+ − 80 #define XBIGNUM(x) XRECORD (x, bignum, Lisp_Bignum)
+ − 81 #define wrap_bignum(p) wrap_record (p, bignum)
+ − 82 #define BIGNUMP(x) RECORDP (x, bignum)
+ − 83 #define CHECK_BIGNUM(x) CHECK_RECORD (x, bignum)
+ − 84 #define CONCHECK_BIGNUM(x) CONCHECK_RECORD (x, bignum)
+ − 85
+ − 86 #define bignum_data(b) (b)->data
+ − 87 #define XBIGNUM_DATA(x) bignum_data (XBIGNUM (x))
+ − 88
+ − 89 #define BIGNUM_ARITH_RETURN(b,op) do \
+ − 90 { \
+ − 91 Lisp_Object retval = make_bignum (0); \
+ − 92 bignum_##op (XBIGNUM_DATA (retval), XBIGNUM_DATA (b)); \
+ − 93 return Fcanonicalize_number (retval); \
+ − 94 } while (0)
+ − 95
+ − 96 #define BIGNUM_ARITH_RETURN1(b,op,arg) do \
+ − 97 { \
+ − 98 Lisp_Object retval = make_bignum(0); \
+ − 99 bignum_##op (XBIGNUM_DATA (retval), XBIGNUM_DATA (b), arg); \
+ − 100 return Fcanonicalize_number (retval); \
+ − 101 } while (0)
+ − 102
3391
+ − 103 #if SIZEOF_EMACS_INT == SIZEOF_LONG
+ − 104 # define bignum_fits_emacs_int_p(b) bignum_fits_long_p(b)
+ − 105 # define bignum_to_emacs_int(b) bignum_to_long(b)
+ − 106 #elif SIZEOF_EMACS_INT == SIZEOF_INT
+ − 107 # define bignum_fits_emacs_int_p(b) bignum_fits_int_p(b)
+ − 108 # define bignum_to_emacs_int(b) bignum_to_int(b)
+ − 109 #else
+ − 110 # error Bignums currently do not work with long long Emacs integers.
+ − 111 #endif
+ − 112
1983
+ − 113 extern Lisp_Object make_bignum (long);
+ − 114 extern Lisp_Object make_bignum_bg (bignum);
+ − 115 extern bignum scratch_bignum, scratch_bignum2;
+ − 116
+ − 117 #else /* !HAVE_BIGNUM */
+ − 118
+ − 119 #define BIGNUMP(x) 0
+ − 120 #define CHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x)
+ − 121 #define CONCHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x)
+ − 122 typedef void bignum;
+ − 123 #define make_bignum(l) This XEmacs does not support bignums
+ − 124 #define make_bignum_bg(b) This XEmacs does not support bignums
+ − 125
+ − 126 #endif /* HAVE_BIGNUM */
+ − 127
2092
+ − 128 extern Lisp_Object Qbignump;
1983
+ − 129 EXFUN (Fbignump, 1);
+ − 130
+ − 131
+ − 132 /********************************* Integers *********************************/
+ − 133 extern Lisp_Object Qintegerp;
+ − 134
+ − 135 #define INTEGERP(x) (INTP(x) || BIGNUMP(x))
+ − 136 #define CHECK_INTEGER(x) do { \
+ − 137 if (!INTEGERP (x)) \
+ − 138 dead_wrong_type_argument (Qintegerp, x); \
+ − 139 } while (0)
+ − 140 #define CONCHECK_INTEGER(x) do { \
+ − 141 if (!INTEGERP (x)) \
+ − 142 x = wrong_type_argument (Qintegerp, x); \
+ − 143 } while (0)
+ − 144
+ − 145 #ifdef HAVE_BIGNUM
+ − 146 #define make_integer(x) \
+ − 147 (NUMBER_FITS_IN_AN_EMACS_INT (x) ? make_int (x) : make_bignum (x))
+ − 148 #else
+ − 149 #define make_integer(x) make_int (x)
+ − 150 #endif
+ − 151
+ − 152 extern Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum;
+ − 153 EXFUN (Fintegerp, 1);
+ − 154 EXFUN (Fevenp, 1);
+ − 155 EXFUN (Foddp, 1);
+ − 156
+ − 157
+ − 158 /********************************** Ratios **********************************/
+ − 159 #ifdef HAVE_RATIO
+ − 160
+ − 161 struct Lisp_Ratio
+ − 162 {
+ − 163 struct lrecord_header lheader;
+ − 164 ratio data;
+ − 165 };
+ − 166 typedef struct Lisp_Ratio Lisp_Ratio;
+ − 167
+ − 168 DECLARE_LRECORD (ratio, Lisp_Ratio);
+ − 169 #define XRATIO(x) XRECORD (x, ratio, Lisp_Ratio)
+ − 170 #define wrap_ratio(p) wrap_record (p, ratio)
+ − 171 #define RATIOP(x) RECORDP (x, ratio)
+ − 172 #define CHECK_RATIO(x) CHECK_RECORD (x, ratio)
+ − 173 #define CONCHECK_RATIO(x) CONCHECK_RECORD (x, ratio)
+ − 174
+ − 175 #define ratio_data(r) (r)->data
+ − 176
+ − 177 #define XRATIO_DATA(r) ratio_data (XRATIO (r))
+ − 178 #define XRATIO_NUMERATOR(r) ratio_numerator (XRATIO_DATA (r))
+ − 179 #define XRATIO_DENOMINATOR(r) ratio_denominator (XRATIO_DATA (r))
+ − 180
+ − 181 #define RATIO_ARITH_RETURN(r,op) do \
+ − 182 { \
+ − 183 Lisp_Object retval = make_ratio (0L, 1UL); \
+ − 184 ratio_##op (XRATIO_DATA (retval), XRATIO_DATA (r)); \
+ − 185 return Fcanonicalize_number (retval); \
+ − 186 } while (0)
+ − 187
+ − 188 #define RATIO_ARITH_RETURN1(r,op,arg) do \
+ − 189 { \
+ − 190 Lisp_Object retval = make_ratio (0L, 1UL); \
+ − 191 ratio_##op (XRATIO_DATA (retval), XRATIO_DATA (r), arg); \
+ − 192 return Fcanonicalize_number (retval); \
+ − 193 } while (0)
+ − 194
+ − 195 extern Lisp_Object make_ratio (long, unsigned long);
+ − 196 extern Lisp_Object make_ratio_bg (bignum, bignum);
+ − 197 extern Lisp_Object make_ratio_rt (ratio);
+ − 198 extern ratio scratch_ratio;
+ − 199
+ − 200 #else /* !HAVE_RATIO */
+ − 201
+ − 202 #define RATIOP(x) 0
+ − 203 #define CHECK_RATIO(x) dead_wrong_type_argument (Qratiop, x)
+ − 204 #define CONCHECK_RATIO(x) dead_wrong_type_argument (Qratiop, x)
+ − 205 typedef void ratio;
+ − 206 #define make_ratio(n,d) This XEmacs does not support ratios
+ − 207 #define make_ratio_bg(n,d) This XEmacs does not support ratios
+ − 208
+ − 209 #endif /* HAVE_RATIO */
+ − 210
2092
+ − 211 extern Lisp_Object Qratiop;
1983
+ − 212 EXFUN (Fratiop, 1);
+ − 213
+ − 214
+ − 215 /******************************** Rationals *********************************/
+ − 216 extern Lisp_Object Qrationalp;
+ − 217
+ − 218 #define RATIONALP(x) (INTEGERP(x) || RATIOP(x))
+ − 219 #define CHECK_RATIONAL(x) do { \
+ − 220 if (!RATIONALP (x)) \
+ − 221 dead_wrong_type_argument (Qrationalp, x); \
+ − 222 } while (0)
+ − 223 #define CONCHECK_RATIONAL(x) do { \
+ − 224 if (!RATIONALP (x)) \
+ − 225 x = wrong_type_argument (Qrationalp, x); \
+ − 226 } while (0)
+ − 227
+ − 228 EXFUN (Frationalp, 1);
+ − 229 EXFUN (Fnumerator, 1);
+ − 230 EXFUN (Fdenominator, 1);
+ − 231
+ − 232
+ − 233 /******************************** Bigfloats *********************************/
+ − 234 #ifdef HAVE_BIGFLOAT
+ − 235 struct Lisp_Bigfloat
+ − 236 {
+ − 237 struct lrecord_header lheader;
+ − 238 bigfloat bf;
+ − 239 };
+ − 240 typedef struct Lisp_Bigfloat Lisp_Bigfloat;
+ − 241
+ − 242 DECLARE_LRECORD (bigfloat, Lisp_Bigfloat);
+ − 243 #define XBIGFLOAT(x) XRECORD (x, bigfloat, Lisp_Bigfloat)
+ − 244 #define wrap_bigfloat(p) wrap_record (p, bigfloat)
+ − 245 #define BIGFLOATP(x) RECORDP (x, bigfloat)
+ − 246 #define CHECK_BIGFLOAT(x) CHECK_RECORD (x, bigfloat)
+ − 247 #define CONCHECK_BIGFLOAT(x) CONCHECK_RECORD (x, bigfloat)
+ − 248
+ − 249 #define bigfloat_data(f) ((f)->bf)
+ − 250 #define XBIGFLOAT_DATA(x) bigfloat_data (XBIGFLOAT (x))
+ − 251 #define XBIGFLOAT_GET_PREC(x) bigfloat_get_prec (XBIGFLOAT_DATA (x))
+ − 252 #define XBIGFLOAT_SET_PREC(x,p) bigfloat_set_prec (XBIGFLOAT_DATA (x), p)
+ − 253
+ − 254 #define BIGFLOAT_ARITH_RETURN(f,op) do \
+ − 255 { \
+ − 256 Lisp_Object retval = make_bigfloat_bf (f); \
+ − 257 bigfloat_##op (XBIGFLOAT_DATA (retval), XBIGFLOAT_DATA (f)); \
+ − 258 return retval; \
+ − 259 } while (0)
+ − 260
+ − 261 #define BIGFLOAT_ARITH_RETURN1(f,op,arg) do \
+ − 262 { \
+ − 263 Lisp_Object retval = make_bigfloat_bf (f); \
+ − 264 bigfloat_##op (XBIGFLOAT_DATA (retval), XBIGFLOAT_DATA (f), arg); \
+ − 265 return retval; \
+ − 266 } while (0)
+ − 267
+ − 268 extern Lisp_Object make_bigfloat (double, unsigned long);
+ − 269 extern Lisp_Object make_bigfloat_bf (bigfloat);
+ − 270 extern Lisp_Object Vdefault_float_precision;
+ − 271 extern bigfloat scratch_bigfloat, scratch_bigfloat2;
+ − 272
+ − 273 #else /* !HAVE_BIGFLOAT */
+ − 274
+ − 275 #define BIGFLOATP(x) 0
+ − 276 #define CHECK_BIGFLOAT(x) dead_wrong_type_argument (Qbigfloatp, x)
+ − 277 #define CONCHECK_BIGFLOAT(x) dead_wrong_type_argument (Qbigfloatp, x)
+ − 278 typedef void bigfloat;
+ − 279 #define make_bigfloat(f) This XEmacs does not support bigfloats
+ − 280 #define make_bigfloat_bf(f) This XEmacs does not support bigfloast
+ − 281
+ − 282 #endif /* HAVE_BIGFLOAT */
+ − 283
2092
+ − 284 extern Lisp_Object Qbigfloatp;
1983
+ − 285 EXFUN (Fbigfloatp, 1);
+ − 286
+ − 287 /********************************* Floating *********************************/
+ − 288 extern Lisp_Object Qfloatingp, Qbigfloat;
+ − 289 extern Lisp_Object Qread_default_float_format, Vread_default_float_format;
+ − 290
+ − 291 #define FLOATINGP(x) (FLOATP (x) || BIGFLOATP (x))
+ − 292 #define CHECK_FLOATING(x) do { \
+ − 293 if (!FLOATINGP (x)) \
+ − 294 dead_wrong_type_argument (Qfloatingp, x); \
+ − 295 } while (0)
+ − 296 #define CONCHECK_FLOATING(x) do { \
+ − 297 if (!FLOATINGP (x)) \
+ − 298 x = wrong_type_argument (Qfloating, x); \
+ − 299 } while (0)
+ − 300
2057
+ − 301 extern Lisp_Object make_floating (double);
1983
+ − 302 EXFUN (Ffloatp, 1);
+ − 303
+ − 304
+ − 305 /********************************** Reals ***********************************/
+ − 306 extern Lisp_Object Qrealp;
+ − 307
+ − 308 #define REALP(x) (RATIONALP (x) || FLOATINGP (x))
+ − 309 #define CHECK_REAL(x) do { \
+ − 310 if (!REALP (x)) \
+ − 311 dead_wrong_type_argument (Qrealp, x); \
+ − 312 } while (0)
+ − 313 #define CONCHECK_REAL(x) do { \
+ − 314 if (!REALP (x)) \
+ − 315 x = wrong_type_argument (Qrealp, x); \
+ − 316 } while (0)
+ − 317
+ − 318 EXFUN (Frealp, 1);
+ − 319
+ − 320
+ − 321 /********************************* Numbers **********************************/
+ − 322 extern Lisp_Object Qnumberp;
+ − 323
+ − 324 #define NUMBERP(x) REALP (x)
+ − 325 #define CHECK_NUMBER(x) do { \
+ − 326 if (!NUMBERP (x)) \
+ − 327 dead_wrong_type_argument (Qnumberp, x); \
+ − 328 } while (0)
+ − 329 #define CONCHECK_NUMBER(x) do { \
+ − 330 if (!NUMBERP (x)) \
+ − 331 x = wrong_type_argument (Qnumberp, x); \
+ − 332 } while (0)
+ − 333
+ − 334 EXFUN (Fcanonicalize_number, 1);
+ − 335
+ − 336 enum number_type {FIXNUM_T, BIGNUM_T, RATIO_T, FLOAT_T, BIGFLOAT_T};
+ − 337
1995
+ − 338 extern enum number_type get_number_type (Lisp_Object);
1983
+ − 339 extern enum number_type promote_args (Lisp_Object *, Lisp_Object *);
+ − 340
+ − 341 #endif /* INCLUDED_number_h_ */