Mercurial > hg > xemacs-beta
comparison src/number.h @ 1983:9c872f33ecbe
[xemacs-hg @ 2004-04-05 22:49:31 by james]
Add bignum, ratio, and bigfloat support.
author | james |
---|---|
date | Mon, 05 Apr 2004 22:50:11 +0000 |
parents | |
children | 4e6a63799f08 |
comparison
equal
deleted
inserted
replaced
1982:a748951fd4fb | 1983:9c872f33ecbe |
---|---|
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 | |
103 extern Lisp_Object make_bignum (long); | |
104 extern Lisp_Object make_bignum_bg (bignum); | |
105 extern bignum scratch_bignum, scratch_bignum2; | |
106 | |
107 #else /* !HAVE_BIGNUM */ | |
108 | |
109 extern Lisp_Object Qbignump; | |
110 #define BIGNUMP(x) 0 | |
111 #define CHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x) | |
112 #define CONCHECK_BIGNUM(x) dead_wrong_type_argument (Qbignump, x) | |
113 typedef void bignum; | |
114 #define make_bignum(l) This XEmacs does not support bignums | |
115 #define make_bignum_bg(b) This XEmacs does not support bignums | |
116 | |
117 #endif /* HAVE_BIGNUM */ | |
118 | |
119 EXFUN (Fbignump, 1); | |
120 | |
121 | |
122 /********************************* Integers *********************************/ | |
123 extern Lisp_Object Qintegerp; | |
124 | |
125 #define INTEGERP(x) (INTP(x) || BIGNUMP(x)) | |
126 #define CHECK_INTEGER(x) do { \ | |
127 if (!INTEGERP (x)) \ | |
128 dead_wrong_type_argument (Qintegerp, x); \ | |
129 } while (0) | |
130 #define CONCHECK_INTEGER(x) do { \ | |
131 if (!INTEGERP (x)) \ | |
132 x = wrong_type_argument (Qintegerp, x); \ | |
133 } while (0) | |
134 | |
135 #ifdef HAVE_BIGNUM | |
136 #define make_integer(x) \ | |
137 (NUMBER_FITS_IN_AN_EMACS_INT (x) ? make_int (x) : make_bignum (x)) | |
138 #else | |
139 #define make_integer(x) make_int (x) | |
140 #endif | |
141 | |
142 extern Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum; | |
143 EXFUN (Fintegerp, 1); | |
144 EXFUN (Fevenp, 1); | |
145 EXFUN (Foddp, 1); | |
146 | |
147 | |
148 /********************************** Ratios **********************************/ | |
149 #ifdef HAVE_RATIO | |
150 | |
151 struct Lisp_Ratio | |
152 { | |
153 struct lrecord_header lheader; | |
154 ratio data; | |
155 }; | |
156 typedef struct Lisp_Ratio Lisp_Ratio; | |
157 | |
158 DECLARE_LRECORD (ratio, Lisp_Ratio); | |
159 #define XRATIO(x) XRECORD (x, ratio, Lisp_Ratio) | |
160 #define wrap_ratio(p) wrap_record (p, ratio) | |
161 #define RATIOP(x) RECORDP (x, ratio) | |
162 #define CHECK_RATIO(x) CHECK_RECORD (x, ratio) | |
163 #define CONCHECK_RATIO(x) CONCHECK_RECORD (x, ratio) | |
164 | |
165 #define ratio_data(r) (r)->data | |
166 | |
167 #define XRATIO_DATA(r) ratio_data (XRATIO (r)) | |
168 #define XRATIO_NUMERATOR(r) ratio_numerator (XRATIO_DATA (r)) | |
169 #define XRATIO_DENOMINATOR(r) ratio_denominator (XRATIO_DATA (r)) | |
170 | |
171 #define RATIO_ARITH_RETURN(r,op) do \ | |
172 { \ | |
173 Lisp_Object retval = make_ratio (0L, 1UL); \ | |
174 ratio_##op (XRATIO_DATA (retval), XRATIO_DATA (r)); \ | |
175 return Fcanonicalize_number (retval); \ | |
176 } while (0) | |
177 | |
178 #define RATIO_ARITH_RETURN1(r,op,arg) do \ | |
179 { \ | |
180 Lisp_Object retval = make_ratio (0L, 1UL); \ | |
181 ratio_##op (XRATIO_DATA (retval), XRATIO_DATA (r), arg); \ | |
182 return Fcanonicalize_number (retval); \ | |
183 } while (0) | |
184 | |
185 extern Lisp_Object make_ratio (long, unsigned long); | |
186 extern Lisp_Object make_ratio_bg (bignum, bignum); | |
187 extern Lisp_Object make_ratio_rt (ratio); | |
188 extern ratio scratch_ratio; | |
189 | |
190 #else /* !HAVE_RATIO */ | |
191 | |
192 extern Lisp_Object Qratiop; | |
193 #define RATIOP(x) 0 | |
194 #define CHECK_RATIO(x) dead_wrong_type_argument (Qratiop, x) | |
195 #define CONCHECK_RATIO(x) dead_wrong_type_argument (Qratiop, x) | |
196 typedef void ratio; | |
197 #define make_ratio(n,d) This XEmacs does not support ratios | |
198 #define make_ratio_bg(n,d) This XEmacs does not support ratios | |
199 | |
200 #endif /* HAVE_RATIO */ | |
201 | |
202 EXFUN (Fratiop, 1); | |
203 | |
204 | |
205 /******************************** Rationals *********************************/ | |
206 extern Lisp_Object Qrationalp; | |
207 | |
208 #define RATIONALP(x) (INTEGERP(x) || RATIOP(x)) | |
209 #define CHECK_RATIONAL(x) do { \ | |
210 if (!RATIONALP (x)) \ | |
211 dead_wrong_type_argument (Qrationalp, x); \ | |
212 } while (0) | |
213 #define CONCHECK_RATIONAL(x) do { \ | |
214 if (!RATIONALP (x)) \ | |
215 x = wrong_type_argument (Qrationalp, x); \ | |
216 } while (0) | |
217 | |
218 EXFUN (Frationalp, 1); | |
219 EXFUN (Fnumerator, 1); | |
220 EXFUN (Fdenominator, 1); | |
221 | |
222 | |
223 /******************************** Bigfloats *********************************/ | |
224 #ifdef HAVE_BIGFLOAT | |
225 struct Lisp_Bigfloat | |
226 { | |
227 struct lrecord_header lheader; | |
228 bigfloat bf; | |
229 }; | |
230 typedef struct Lisp_Bigfloat Lisp_Bigfloat; | |
231 | |
232 DECLARE_LRECORD (bigfloat, Lisp_Bigfloat); | |
233 #define XBIGFLOAT(x) XRECORD (x, bigfloat, Lisp_Bigfloat) | |
234 #define wrap_bigfloat(p) wrap_record (p, bigfloat) | |
235 #define BIGFLOATP(x) RECORDP (x, bigfloat) | |
236 #define CHECK_BIGFLOAT(x) CHECK_RECORD (x, bigfloat) | |
237 #define CONCHECK_BIGFLOAT(x) CONCHECK_RECORD (x, bigfloat) | |
238 | |
239 #define bigfloat_data(f) ((f)->bf) | |
240 #define XBIGFLOAT_DATA(x) bigfloat_data (XBIGFLOAT (x)) | |
241 #define XBIGFLOAT_GET_PREC(x) bigfloat_get_prec (XBIGFLOAT_DATA (x)) | |
242 #define XBIGFLOAT_SET_PREC(x,p) bigfloat_set_prec (XBIGFLOAT_DATA (x), p) | |
243 | |
244 #define BIGFLOAT_ARITH_RETURN(f,op) do \ | |
245 { \ | |
246 Lisp_Object retval = make_bigfloat_bf (f); \ | |
247 bigfloat_##op (XBIGFLOAT_DATA (retval), XBIGFLOAT_DATA (f)); \ | |
248 return retval; \ | |
249 } while (0) | |
250 | |
251 #define BIGFLOAT_ARITH_RETURN1(f,op,arg) do \ | |
252 { \ | |
253 Lisp_Object retval = make_bigfloat_bf (f); \ | |
254 bigfloat_##op (XBIGFLOAT_DATA (retval), XBIGFLOAT_DATA (f), arg); \ | |
255 return retval; \ | |
256 } while (0) | |
257 | |
258 extern Lisp_Object make_bigfloat (double, unsigned long); | |
259 extern Lisp_Object make_bigfloat_bf (bigfloat); | |
260 extern Lisp_Object Vdefault_float_precision; | |
261 extern bigfloat scratch_bigfloat, scratch_bigfloat2; | |
262 | |
263 #else /* !HAVE_BIGFLOAT */ | |
264 | |
265 extern Lisp_Object Qbigfloatp; | |
266 #define BIGFLOATP(x) 0 | |
267 #define CHECK_BIGFLOAT(x) dead_wrong_type_argument (Qbigfloatp, x) | |
268 #define CONCHECK_BIGFLOAT(x) dead_wrong_type_argument (Qbigfloatp, x) | |
269 typedef void bigfloat; | |
270 #define make_bigfloat(f) This XEmacs does not support bigfloats | |
271 #define make_bigfloat_bf(f) This XEmacs does not support bigfloast | |
272 | |
273 #endif /* HAVE_BIGFLOAT */ | |
274 | |
275 EXFUN (Fbigfloatp, 1); | |
276 | |
277 /********************************* Floating *********************************/ | |
278 extern Lisp_Object Qfloatingp, Qbigfloat; | |
279 extern Lisp_Object Qread_default_float_format, Vread_default_float_format; | |
280 | |
281 #define FLOATINGP(x) (FLOATP (x) || BIGFLOATP (x)) | |
282 #define CHECK_FLOATING(x) do { \ | |
283 if (!FLOATINGP (x)) \ | |
284 dead_wrong_type_argument (Qfloatingp, x); \ | |
285 } while (0) | |
286 #define CONCHECK_FLOATING(x) do { \ | |
287 if (!FLOATINGP (x)) \ | |
288 x = wrong_type_argument (Qfloating, x); \ | |
289 } while (0) | |
290 | |
291 EXFUN (Ffloatp, 1); | |
292 | |
293 | |
294 /********************************** Reals ***********************************/ | |
295 extern Lisp_Object Qrealp; | |
296 | |
297 #define REALP(x) (RATIONALP (x) || FLOATINGP (x)) | |
298 #define CHECK_REAL(x) do { \ | |
299 if (!REALP (x)) \ | |
300 dead_wrong_type_argument (Qrealp, x); \ | |
301 } while (0) | |
302 #define CONCHECK_REAL(x) do { \ | |
303 if (!REALP (x)) \ | |
304 x = wrong_type_argument (Qrealp, x); \ | |
305 } while (0) | |
306 | |
307 EXFUN (Frealp, 1); | |
308 | |
309 | |
310 /********************************* Numbers **********************************/ | |
311 extern Lisp_Object Qnumberp; | |
312 | |
313 #define NUMBERP(x) REALP (x) | |
314 #define CHECK_NUMBER(x) do { \ | |
315 if (!NUMBERP (x)) \ | |
316 dead_wrong_type_argument (Qnumberp, x); \ | |
317 } while (0) | |
318 #define CONCHECK_NUMBER(x) do { \ | |
319 if (!NUMBERP (x)) \ | |
320 x = wrong_type_argument (Qnumberp, x); \ | |
321 } while (0) | |
322 | |
323 EXFUN (Fcanonicalize_number, 1); | |
324 | |
325 enum number_type {FIXNUM_T, BIGNUM_T, RATIO_T, FLOAT_T, BIGFLOAT_T}; | |
326 | |
327 extern enum number_type promote_args (Lisp_Object *, Lisp_Object *); | |
328 | |
329 #endif /* INCLUDED_number_h_ */ |