comparison src/number.c @ 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 /* 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 #include <config.h>
24 #include <limits.h>
25 #include "lisp.h"
26
27 Lisp_Object Qintegerp, Qrationalp, Qfloatingp, Qrealp, Qnumberp;
28 Lisp_Object Vdefault_float_precision;
29 Fixnum Vmost_negative_fixnum, Vmost_positive_fixnum;
30 static Lisp_Object Qunsupported_type;
31 static Lisp_Object Vbigfloat_max_prec;
32 static int number_initialized;
33
34 #ifdef HAVE_BIGNUM
35 bignum scratch_bignum, scratch_bignum2;
36 #endif
37 #ifdef HAVE_RATIO
38 ratio scratch_ratio;
39 #endif
40 #ifdef HAVE_BIGFLOAT
41 bigfloat scratch_bigfloat, scratch_bigfloat2;
42 #endif
43
44 /********************************* Bignums **********************************/
45 #ifdef HAVE_BIGNUM
46 static void
47 bignum_print (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
48 {
49 CIbyte *bstr = bignum_to_string (XBIGNUM_DATA (obj), 10);
50 write_c_string (printcharfun, bstr);
51 xfree (bstr, CIbyte *);
52 }
53
54 static void
55 bignum_finalize (void *header, int for_disksave)
56 {
57 if (for_disksave)
58 invalid_operation ("Can't dump an XEmacs containing bignum objects",
59 VOID_TO_LISP (header));
60 bignum_fini (((Lisp_Bignum *)header)->data);
61 }
62
63 static int
64 bignum_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
65 {
66 return bignum_eql (XBIGNUM_DATA (obj1), XBIGNUM_DATA (obj2));
67 }
68
69 static Hashcode
70 bignum_hash (Lisp_Object obj, int depth)
71 {
72 return bignum_hashcode (XBIGNUM_DATA (obj));
73 }
74
75 static const struct memory_description bignum_description[] = {
76 { XD_OPAQUE_PTR, offsetof (Lisp_Bignum, data) },
77 { XD_END }
78 };
79
80 DEFINE_LRECORD_IMPLEMENTATION ("bignum", bignum, 0, 0,
81 bignum_print, bignum_finalize, bignum_equal,
82 bignum_hash, bignum_description, Lisp_Bignum);
83
84 Lisp_Object
85 string_to_bignum(const Ibyte *str, Bytecount len, int base)
86 {
87 Lisp_Object b = make_bignum (0L);
88 return (bignum_set_string (XBIGNUM_DATA (b), str, base) < 0)
89 ? Fsignal (Qinvalid_read_syntax,
90 list3 (build_msg_string
91 ("Invalid integer constant in reader"),
92 make_string (str, len),
93 make_int (10)))
94 : b;
95 }
96
97 #else /* !HAVE_BIGNUM */
98
99 Lisp_Object Qbignump;
100
101 #endif /* HAVE_BIGNUM */
102
103 DEFUN ("bignump", Fbignump, 1, 1, 0, /*
104 Return t if OBJECT is a bignum, nil otherwise.
105 */
106 (object))
107 {
108 return BIGNUMP (object) ? Qt : Qnil;
109 }
110
111
112 /********************************* Integers *********************************/
113 DEFUN ("integerp", Fintegerp, 1, 1, 0, /*
114 Return t if OBJECT is an integer, nil otherwise.
115 */
116 (object))
117 {
118 return INTEGERP (object) ? Qt : Qnil;
119 }
120
121 DEFUN ("evenp", Fevenp, 1, 1, 0, /*
122 Return t if INTEGER is even, nil otherwise.
123 */
124 (integer))
125 {
126 CONCHECK_INTEGER (integer);
127 return BIGNUMP (integer)
128 ? bignum_evenp (XBIGNUM_DATA (integer))
129 : XTYPE (integer) == Lisp_Type_Int_Even;
130 }
131
132 DEFUN ("odd", Foddp, 1, 1, 0, /*
133 Return t if INTEGER is odd, nil otherwise.
134 */
135 (integer))
136 {
137 CONCHECK_INTEGER (integer);
138 return BIGNUMP (integer)
139 ? bignum_oddp (XBIGNUM_DATA (integer))
140 : XTYPE (integer) == Lisp_Type_Int_Odd;
141 }
142
143
144 /********************************** Ratios **********************************/
145 #ifdef HAVE_RATIO
146 static void
147 ratio_print (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
148 {
149 CIbyte *rstr = ratio_to_string (XRATIO_DATA (obj), 10);
150 write_c_string (printcharfun, rstr);
151 xfree (rstr, CIbyte *);
152 }
153
154 static void
155 ratio_finalize (void *header, int for_disksave)
156 {
157 if (for_disksave)
158 invalid_operation ("Can't dump an XEmacs containing ratio objects",
159 VOID_TO_LISP (header));
160 ratio_fini (((Lisp_Ratio *)header)->data);
161 }
162 ;
163
164 static int
165 ratio_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
166 {
167 return ratio_eql (XRATIO_DATA (obj1), XRATIO_DATA (obj2));
168 }
169
170 static Hashcode
171 ratio_hash (Lisp_Object obj, int depth)
172 {
173 return ratio_hashcode (XRATIO_DATA (obj));
174 }
175
176 static const struct memory_description ratio_description[] = {
177 { XD_OPAQUE_PTR, offsetof (Lisp_Ratio, data) },
178 { XD_END }
179 };
180
181 DEFINE_LRECORD_IMPLEMENTATION ("ratio", ratio, 0, 0,
182 ratio_print, ratio_finalize, ratio_equal,
183 ratio_hash, ratio_description, Lisp_Ratio);
184
185 #else /* !HAVE_RATIO */
186
187 Lisp_Object Qratiop;
188
189 #endif /* HAVE_RATIO */
190
191 DEFUN ("ratiop", Fratiop, 1, 1, 0, /*
192 Return t if OBJECT is a ratio, nil otherwise.
193 */
194 (object))
195 {
196 return RATIOP (object) ? Qt : Qnil;
197 }
198
199
200 /******************************** Rationals *********************************/
201 DEFUN ("rationalp", Frationalp, 1, 1, 0, /*
202 Return t if OBJECT is a rational, nil otherwise.
203 */
204 (object))
205 {
206 return RATIONALP (object) ? Qt : Qnil;
207 }
208
209 DEFUN ("numerator", Fnumerator, 1, 1, 0, /*
210 Return the numerator of the canonical form of RATIONAL.
211 If RATIONAL is an integer, RATIONAL is returned.
212 */
213 (rational))
214 {
215 CONCHECK_RATIONAL (rational);
216 #ifdef HAVE_RATIO
217 return RATIOP (rational)
218 ? make_bignum_bg (XRATIO_NUMERATOR (rational))
219 : rational;
220 #else
221 return rational;
222 #endif
223 }
224
225 DEFUN ("denominator", Fdenominator, 1, 1, 0, /*
226 Return the denominator of the canonical form of RATIONAL.
227 If RATIONAL is an integer, 1 is returned.
228 */
229 (rational))
230 {
231 CONCHECK_RATIONAL (rational);
232 #ifdef HAVE_RATIO
233 return RATIOP (rational)
234 ? make_bignum_bg (XRATIO_DENOMINATOR (rational))
235 : make_int (1);
236 #else
237 return rational;
238 #endif
239 }
240
241
242 /******************************** Bigfloats *********************************/
243 #ifdef HAVE_BIGFLOAT
244 static void
245 bigfloat_print (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
246 {
247 CIbyte *fstr = bigfloat_to_string (XBIGFLOAT_DATA (obj), 10);
248 write_c_string (printcharfun, fstr);
249 xfree (fstr, CIbyte *);
250 }
251
252 static void
253 bigfloat_finalize (void *header, int for_disksave)
254 {
255 if (for_disksave)
256 invalid_operation ("Can't dump an XEmacs containing bigfloat objects",
257 VOID_TO_LISP (header));
258 bigfloat_fini (((Lisp_Bigfloat *)header)->bf);
259 }
260
261 static int
262 bigfloat_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
263 {
264 return bigfloat_eql (XBIGFLOAT_DATA (obj1), XBIGFLOAT_DATA (obj2));
265 }
266
267 static Hashcode
268 bigfloat_hash (Lisp_Object obj, int depth)
269 {
270 return bigfloat_hashcode (XBIGFLOAT_DATA (obj));
271 }
272
273 static const struct memory_description bigfloat_description[] = {
274 { XD_OPAQUE_PTR, offsetof (Lisp_Bigfloat, bf) },
275 { XD_END }
276 };
277
278 DEFINE_LRECORD_IMPLEMENTATION ("bigfloat", bigfloat, 1, 0,
279 bigfloat_print, bigfloat_finalize,
280 bigfloat_equal, bigfloat_hash,
281 bigfloat_description, Lisp_Bigfloat);
282
283 #else /* !HAVE_BIGFLOAT */
284
285 Lisp_Object Qbigfloatp;
286
287 #endif /* HAVE_BIGFLOAT */
288
289 DEFUN ("bigfloatp", Fbigfloatp, 1, 1, 0, /*
290 Return t if OBJECT is a bigfloat, nil otherwise.
291 */
292 (object))
293 {
294 return BIGFLOATP (object) ? Qt : Qnil;
295 }
296
297 static int
298 default_float_precision_changed (Lisp_Object sym, Lisp_Object *val,
299 Lisp_Object in_object, int flags)
300 {
301 unsigned long prec;
302
303 CONCHECK_INTEGER (*val);
304 #ifdef HAVE_BIGFLOAT
305 if (INTP (*val))
306 prec = XINT (*val);
307 else
308 {
309 if (!bignum_fits_ulong_p (XBIGNUM_DATA (*val)))
310 args_out_of_range_3 (*val, Qzero, Vbigfloat_max_prec);
311 prec = bignum_to_ulong (XBIGNUM_DATA (*val));
312 }
313 if (prec != 0UL)
314 bigfloat_set_default_prec (prec);
315 #endif
316 return 0;
317 }
318
319
320 /********************************* Floating *********************************/
321 Lisp_Object
322 make_floating (double d)
323 {
324 #ifdef HAVE_BIGFLOAT
325 if (ZEROP (Vdefault_float_precision))
326 #endif
327 return make_float (d);
328 #ifdef HAVE_BIGFLOAT
329 else
330 return make_bigfloat (d, 0UL);
331 #endif
332 }
333
334 DEFUN ("floatingp", Ffloatingp, 1, 1, 0, /*
335 Return t if OBJECT is a floating point number of any kind, nil otherwise.
336 */
337 (object))
338 {
339 return FLOATINGP (object) ? Qt : Qnil;
340 }
341
342
343 /********************************** Reals ***********************************/
344 DEFUN ("realp", Frealp, 1, 1, 0, /*
345 Return t if OBJECT is a real, nil otherwise.
346 */
347 (object))
348 {
349 return REALP (object) ? Qt : Qnil;
350 }
351
352
353 /********************************* Numbers **********************************/
354 DEFUN ("canonicalize-number", Fcanonicalize_number, 1, 1, 0, /*
355 Return the canonical form of NUMBER.
356 */
357 (number))
358 {
359 /* The tests should go in order from larger, more expressive, or more
360 complex types to smaller, less expressive, or simpler types so that a
361 number can cascade all the way down to the simplest type if
362 appropriate. */
363 #ifdef HAVE_RATIO
364 if (RATIOP (number) &&
365 bignum_fits_long_p (XRATIO_DENOMINATOR (number)) &&
366 bignum_to_long (XRATIO_DENOMINATOR (number)) == 1L)
367 number = make_bignum_bg (XRATIO_NUMERATOR (number));
368 #endif
369 #ifdef HAVE_BIGNUM
370 if (BIGNUMP (number) && bignum_fits_int_p (XBIGNUM_DATA (number)))
371 {
372 int n = bignum_to_int (XBIGNUM_DATA (number));
373 if (NUMBER_FITS_IN_AN_EMACS_INT (n))
374 number = make_int (n);
375 }
376 #endif
377 return number;
378 }
379
380 enum number_type
381 get_number_type (Lisp_Object arg)
382 {
383 if (INTP (arg))
384 return FIXNUM_T;
385 #ifdef HAVE_BIGNUM
386 if (BIGNUMP (arg))
387 return BIGNUM_T;
388 #endif
389 #ifdef HAVE_RATIO
390 if (RATIOP (arg))
391 return RATIO_T;
392 #endif
393 if (FLOATP (arg))
394 return FLOAT_T;
395 #ifdef HAVE_BIGFLOAT
396 if (BIGFLOATP (arg))
397 return BIGFLOAT_T;
398 #endif
399 /* Catch unintentional bad uses of this function */
400 abort ();
401 }
402
403 /* Convert NUMBER to type TYPE. If TYPE is BIGFLOAT_T then use the indicated
404 PRECISION; otherwise, PRECISION is ignored. */
405 static Lisp_Object
406 internal_coerce_number (Lisp_Object number, enum number_type type,
407 unsigned long precision)
408 {
409 enum number_type current_type;
410
411 if (CHARP (number))
412 number = make_int (XCHAR (number));
413 else if (MARKERP (number))
414 number = make_int (marker_position (number));
415
416 /* Note that CHECK_NUMBER ensures that NUMBER is a supported type. Hence,
417 we abort() in the #else sections below, because it shouldn't be possible
418 to arrive there. */
419 CHECK_NUMBER (number);
420 current_type = get_number_type (number);
421 switch (current_type)
422 {
423 case FIXNUM_T:
424 switch (type)
425 {
426 case FIXNUM_T:
427 return number;
428 case BIGNUM_T:
429 #ifdef HAVE_BIGNUM
430 return make_bignum (XREALINT (number));
431 #else
432 abort ();
433 #endif /* HAVE_BIGNUM */
434 case RATIO_T:
435 #ifdef HAVE_RATIO
436 return make_ratio (XREALINT (number), 1UL);
437 #else
438 abort ();
439 #endif /* HAVE_RATIO */
440 case FLOAT_T:
441 return make_float (XREALINT (number));
442 case BIGFLOAT_T:
443 #ifdef HAVE_BIGFLOAT
444 return make_bigfloat (XREALINT (number), precision);
445 #else
446 abort ();
447 #endif /* HAVE_BIGFLOAT */
448 }
449 case BIGNUM_T:
450 #ifdef HAVE_BIGNUM
451 switch (type)
452 {
453 case FIXNUM_T:
454 return make_int (bignum_to_long (XBIGNUM_DATA (number)));
455 case BIGNUM_T:
456 return number;
457 case RATIO_T:
458 #ifdef HAVE_RATIO
459 bignum_set_long (scratch_bignum, 1L);
460 return make_ratio_bg (XBIGNUM_DATA (number), scratch_bignum);
461 #else
462 abort ();
463 #endif /* HAVE_RATIO */
464 case FLOAT_T:
465 return make_float (bignum_to_double (XBIGNUM_DATA (number)));
466 case BIGFLOAT_T:
467 #ifdef HAVE_BIGFLOAT
468 {
469 Lisp_Object temp;
470 temp = make_bigfloat (0.0, precision);
471 bigfloat_set_bignum (XBIGFLOAT_DATA (temp), XBIGNUM_DATA (number));
472 return temp;
473 }
474 #else
475 abort ();
476 #endif /* HAVE_BIGFLOAT */
477 }
478 #else
479 abort ();
480 #endif /* HAVE_BIGNUM */
481 case RATIO_T:
482 #ifdef HAVE_RATIO
483 switch (type)
484 {
485 case FIXNUM_T:
486 bignum_div (scratch_bignum, XRATIO_NUMERATOR (number),
487 XRATIO_DENOMINATOR (number));
488 return make_int (bignum_to_long (scratch_bignum));
489 case BIGNUM_T:
490 bignum_div (scratch_bignum, XRATIO_NUMERATOR (number),
491 XRATIO_DENOMINATOR (number));
492 return make_bignum_bg (scratch_bignum);
493 case RATIO_T:
494 return number;
495 case FLOAT_T:
496 return make_float (ratio_to_double (XRATIO_DATA (number)));
497 case BIGFLOAT_T:
498 #ifdef HAVE_BIGFLOAT
499 {
500 Lisp_Object temp;
501 temp = make_bigfloat (0.0, precision);
502 bigfloat_set_ratio (XBIGFLOAT_DATA (temp), XRATIO_DATA (number));
503 return temp;
504 }
505 #else
506 abort ();
507 #endif /* HAVE_BIGFLOAT */
508 }
509 #else
510 abort ();
511 #endif /* HAVE_RATIO */
512 case FLOAT_T:
513 switch (type)
514 {
515 case FIXNUM_T:
516 return Fround (number);
517 case BIGNUM_T:
518 #ifdef HAVE_BIGNUM
519 bignum_set_double (scratch_bignum, XFLOAT_DATA (number));
520 return make_bignum_bg (scratch_bignum);
521 #else
522 abort ();
523 #endif /* HAVE_BIGNUM */
524 case RATIO_T:
525 #ifdef HAVE_RATIO
526 ratio_set_double (scratch_ratio, XFLOAT_DATA (number));
527 return make_ratio_rt (scratch_ratio);
528 #else
529 abort ();
530 #endif /* HAVE_RATIO */
531 case FLOAT_T:
532 return number;
533 case BIGFLOAT_T:
534 #ifdef HAVE_BIGFLOAT
535 bigfloat_set_prec (scratch_bigfloat, precision);
536 bigfloat_set_double (scratch_bigfloat, XFLOAT_DATA (number));
537 return make_bigfloat_bf (scratch_bigfloat);
538 #else
539 abort ();
540 #endif /* HAVE_BIGFLOAT */
541 }
542 case BIGFLOAT_T:
543 #ifdef HAVE_BIGFLOAT
544 switch (type)
545 {
546 case FIXNUM_T:
547 return make_int (bigfloat_to_long (XBIGFLOAT_DATA (number)));
548 case BIGNUM_T:
549 #ifdef HAVE_BIGNUM
550 bignum_set_bigfloat (scratch_bignum, XBIGFLOAT_DATA (number));
551 return make_bignum_bg (scratch_bignum);
552 #else
553 abort ();
554 #endif /* HAVE_BIGNUM */
555 case RATIO_T:
556 #ifdef HAVE_RATIO
557 ratio_set_bigfloat (scratch_ratio, XBIGFLOAT_DATA (number));
558 return make_ratio_rt (scratch_ratio);
559 #else
560 abort ();
561 #endif
562 case FLOAT_T:
563 return make_float (bigfloat_to_double (XBIGFLOAT_DATA (number)));
564 case BIGFLOAT_T:
565 /* FIXME: Do we need to change the precision? */
566 return number;
567 }
568 #else
569 abort ();
570 #endif /* HAVE_BIGFLOAT */
571 }
572 abort ();
573 }
574
575 /* This function promotes its arguments as necessary to make them both the
576 same type. It destructively modifies its arguments to do so. Characters
577 and markers are ALWAYS converted to integers. */
578 enum number_type
579 promote_args (Lisp_Object *arg1, Lisp_Object *arg2)
580 {
581 enum number_type type1, type2;
582
583 if (CHARP (*arg1))
584 *arg1 = make_int (XCHAR (*arg1));
585 else if (MARKERP (*arg1))
586 *arg1 = make_int (marker_position (*arg1));
587 if (CHARP (*arg2))
588 *arg2 = make_int (XCHAR (*arg2));
589 else if (MARKERP (*arg2))
590 *arg2 = make_int (marker_position (*arg2));
591
592 CHECK_NUMBER (*arg1);
593 CHECK_NUMBER (*arg2);
594
595 type1 = get_number_type (*arg1);
596 type2 = get_number_type (*arg2);
597
598 if (type1 < type2)
599 {
600 *arg1 = internal_coerce_number (*arg1, type2,
601 #ifdef HAVE_BIGFLOAT
602 type2 == BIGFLOAT_T
603 ? XBIGFLOAT_GET_PREC (*arg2) :
604 #endif
605 0UL);
606 return type2;
607 }
608
609 if (type2 < type1)
610 {
611 *arg2 = internal_coerce_number (*arg2, type1,
612 #ifdef HAVE_BIGFLOAT
613 type1 == BIGFLOAT_T
614 ? XBIGFLOAT_GET_PREC (*arg1) :
615 #endif
616 0UL);
617 return type1;
618 }
619
620 /* No conversion necessary */
621 return type1;
622 }
623
624 DEFUN ("coerce-number", Fcoerce_number, 2, 3, 0, /*
625 Convert NUMBER to the indicated type, possibly losing information.
626 Do not call this function. Use `coerce' instead.
627
628 TYPE is one of the symbols 'fixnum, 'integer, 'ratio, 'float, or 'bigfloat.
629 Not all of these types may be supported.
630
631 PRECISION is the number of bits of precision to use when converting to
632 bigfloat; it is ignored otherwise. If nil, the default precision is used.
633
634 Note that some conversions lose information. No error is signaled in such
635 cases; the information is silently lost.
636 */
637 (number, type, precision))
638 {
639 CHECK_SYMBOL (type);
640 if (EQ (type, Qfixnum))
641 return internal_coerce_number (number, FIXNUM_T, 0UL);
642 else if (EQ (type, Qinteger))
643 {
644 /* If bignums are available, we always convert to one first, then
645 downgrade to a fixnum if possible. */
646 #ifdef HAVE_BIGNUM
647 return Fcanonicalize_number
648 (internal_coerce_number (number, BIGNUM_T, 0UL));
649 #else
650 return internal_coerce_number (number, FIXNUM_T, 0UL);
651 #endif
652 }
653 #ifdef HAVE_RATIO
654 else if (EQ (type, Qratio))
655 return internal_coerce_number (number, RATIO_T, 0UL);
656 #endif
657 else if (EQ (type, Qfloat))
658 return internal_coerce_number (number, FLOAT_T, 0UL);
659 #ifdef HAVE_BIGFLOAT
660 else if (EQ (type, Qbigfloat))
661 {
662 unsigned long prec;
663
664 if (NILP (precision))
665 prec = bigfloat_get_default_prec ();
666 else
667 {
668 CHECK_INTEGER (precision);
669 #ifdef HAVE_BIGNUM
670 if (INTP (precision))
671 #endif /* HAVE_BIGNUM */
672 prec = (unsigned long) XREALINT (precision);
673 #ifdef HAVE_BIGNUM
674 else
675 {
676 if (!bignum_fits_ulong_p (XBIGNUM_DATA (precision)))
677 args_out_of_range (precision, Vbigfloat_max_prec);
678 prec = bignum_to_ulong (XBIGNUM_DATA (precision));
679 }
680 #endif /* HAVE_BIGNUM */
681 }
682 return internal_coerce_number (number, BIGFLOAT_T, prec);
683 }
684 #endif /* HAVE_BIGFLOAT */
685
686 Fsignal (Qunsupported_type, type);
687 /* NOTREACHED */
688 return Qnil;
689 }
690
691
692 void
693 syms_of_number (void)
694 {
695 #ifdef HAVE_BIGNUM
696 INIT_LRECORD_IMPLEMENTATION (bignum);
697 #endif
698 #ifdef HAVE_RATIO
699 INIT_LRECORD_IMPLEMENTATION (ratio);
700 #endif
701 #ifdef HAVE_BIGFLOAT
702 INIT_LRECORD_IMPLEMENTATION (bigfloat);
703 #endif
704
705 /* Type predicates */
706 DEFSYMBOL (Qintegerp);
707 DEFSYMBOL (Qrationalp);
708 DEFSYMBOL (Qfloatingp);
709 DEFSYMBOL (Qrealp);
710 DEFSYMBOL (Qnumberp);
711 #ifndef HAVE_BIGNUM
712 DEFSYMBOL (Qbignump);
713 #endif
714 #ifndef HAVE_RATIO
715 DEFSYMBOL (Qratiop);
716 #endif
717 #ifndef HAVE_BIGFLOAT
718 DEFSYMBOL (Qbigfloatp);
719 #endif
720
721 /* Functions */
722 DEFSUBR (Fbignump);
723 DEFSUBR (Fintegerp);
724 DEFSUBR (Fevenp);
725 DEFSUBR (Foddp);
726 DEFSUBR (Fratiop);
727 DEFSUBR (Frationalp);
728 DEFSUBR (Fnumerator);
729 DEFSUBR (Fdenominator);
730 DEFSUBR (Fbigfloatp);
731 DEFSUBR (Frealp);
732 DEFSUBR (Fcanonicalize_number);
733 DEFSUBR (Fcoerce_number);
734
735 /* Errors */
736 DEFERROR_STANDARD (Qunsupported_type, Qwrong_type_argument);
737 }
738
739 void
740 vars_of_number (void)
741 {
742 /* This variable is a Lisp variable rather than a number variable so that we
743 can put bignums in it. */
744 DEFVAR_LISP_MAGIC ("default-float-precision", &Vdefault_float_precision, /*
745 The default floating-point precision for newly created floating point values.
746 This should be 0 for the precision of the machine-supported floating point
747 type (the C double type), or an unsigned integer no greater than
748 bigfloat-max-prec (currently the size of a C unsigned long).
749 */ default_float_precision_changed);
750 Vdefault_float_precision = make_int (0);
751
752 DEFVAR_CONST_LISP ("bigfloat-max-prec", &Vbigfloat_max_prec /*
753 The maximum number of bits of precision a bigfloat can have.
754 This is currently the value of ULONG_MAX on the target machine.
755 */);
756
757 DEFVAR_CONST_INT ("most-negative-fixnum", &Vmost_negative_fixnum /*
758 The fixnum closest in value to negative infinity.
759 */);
760 Vmost_negative_fixnum = EMACS_INT_MIN;
761
762 DEFVAR_CONST_INT ("most-positive-fixnum", &Vmost_positive_fixnum /*
763 The fixnum closest in value to positive infinity.
764 */);
765 Vmost_positive_fixnum = EMACS_INT_MAX;
766
767 Fprovide (intern ("number-types"));
768 #ifdef HAVE_BIGNUM
769 Fprovide (intern ("bignum"));
770 #endif
771 #ifdef HAVE_RATIO
772 Fprovide (intern ("ratio"));
773 #endif
774 #ifdef HAVE_BIGFLOAT
775 Fprovide (intern ("bigfloat"));
776 #endif
777 }
778
779 void
780 init_number (void)
781 {
782 if (!number_initialized)
783 {
784 number_initialized = 1;
785
786 #ifdef WITH_GMP
787 init_number_gmp ();
788 #endif
789 #ifdef WITH_MP
790 init_number_mp ();
791 #endif
792
793 #if defined(BIGNUM) && defined(BIGFLOAT)
794 Vbigfloat_max_prec = make_bignum (0L);
795 bignum_set_ulong (XBIGNUM_DATA (Vbigfloat_max_prec), ULONG_MAX);
796 #endif
797
798 #ifdef HAVE_BIGNUM
799 bignum_init (scratch_bignum);
800 bignum_init (scratch_bignum2);
801 #endif
802
803 #ifdef HAVE_RATIO
804 ratio_init (scratch_ratio);
805 #endif
806
807 #ifdef HAVE_BIGFLOAT
808 bigfloat_init (scratch_bigfloat);
809 bigfloat_init (scratch_bigfloat2);
810 #endif
811 }
812 }