Add prompt stack for recursive minibuffer
[sxemacs] / src / ent / ent-mpfr.c
1 /*
2   ent-mpfr.c -- Numeric types for SXEmacs
3   Copyright (C) 2005, 2006 Sebastian Freundt
4
5   Author:  Sebastian Freundt
6
7 This file is part of SXEmacs
8
9 SXEmacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 SXEmacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
21
22
23 #include <config.h>
24 #include <limits.h>
25 #include <math.h>
26 #include "lisp.h"
27 #include "sysproc.h"    /* For qxe_getpid */
28
29 #include "ent-mpfr.h"
30
31 \f
32 Lisp_Object Veuler;
33 Lisp_Object Veuler_mascheroni;
34 Lisp_Object Vpi;
35
36 bigfr ent_scratch_bigfr;
37 static ase_nullary_operation_f Qent_mpfr_zero, Qent_mpfr_one;
38
39 \f
40 static void
41 bigfr_print(Lisp_Object obj, Lisp_Object printcharfun, int SXE_UNUSED(unused))
42 {
43         Bufbyte *fstr = bigfr_to_string(XBIGFR_DATA(obj), 10);
44         write_c_string((char*)fstr, printcharfun);
45         xfree(fstr);
46         fstr = (Bufbyte *)NULL;
47         return;
48 }
49
50 static int
51 bigfr_equal (Lisp_Object obj1, Lisp_Object obj2, int unused)
52 {
53         return bigfr_eq(XBIGFR_DATA(obj1), XBIGFR_DATA(obj2));
54 }
55
56 static unsigned long
57 bigfr_hash (Lisp_Object obj, int unused)
58 {
59         return bigfr_hashcode(XBIGFR_DATA(obj));
60 }
61
62 static Lisp_Object
63 bigfr_mark (Lisp_Object unused)
64 {
65         return Qnil;
66 }
67
68 static void
69 bigfr_finalise (void *header, int for_disksave)
70 {
71         if (for_disksave)
72                 signal_simple_error
73                         ("Can't dump an emacs containing MPFR objects", Qt);
74
75         /* less warnings */
76         if (header);
77 }
78
79 static const struct lrecord_description bigfr_description[] = {
80         { XD_OPAQUE_DATA_PTR, offsetof(Lisp_Bigfr, data) },
81         { XD_END }
82 };
83
84 DEFINE_BASIC_LRECORD_IMPLEMENTATION("bigfr", bigfr,
85                                     bigfr_mark, bigfr_print, bigfr_finalise,
86                                     bigfr_equal, bigfr_hash,
87                                     bigfr_description, Lisp_Bigfr);
88
89
90 DEFUN ("bigfr-get-precision", Fbigfr_get_precision, 1, 1, 0, /*
91 Return the precision of bigfr F as an integer.
92 */
93        (f))
94 {
95         CHECK_BIGFR(f);
96         return make_integer((signed long)XBIGFR_GET_PREC(f));
97 }
98
99 #ifndef MPFR_PREC_MIN
100 #define MPFR_PREC_MIN 2UL
101 #endif
102
103 DEFUN ("bigfr-set-precision", Fbigfr_set_precision, 2, 2, 0, /*
104 Set the precision of F, a bigfr, to PRECISION, a nonnegative integer.
105 The new precision of F is returned.  Note that the return value may differ
106 from PRECISION if the underlying library is unable to support exactly
107 PRECISION bits of precision.
108 */
109        (f, precision))
110 {
111         unsigned long prec;
112
113         CHECK_BIGFR(f);
114         if (INTP(precision)) {
115                 prec = (XINT(precision) <= 0)
116                         ? MPFR_PREC_MIN : (unsigned long)XINT(precision);
117         }
118 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
119         else if (BIGZP(precision)) {
120                 prec = bigz_fits_ulong_p(XBIGZ_DATA(precision))
121                         ? bigz_to_ulong(XBIGZ_DATA(precision))
122                         : UINT_MAX;
123         }
124 #endif  /* HAVE_MPZ */
125         else {
126                 dead_wrong_type_argument(Qintegerp, f);
127                 return Qnil;
128         }
129
130         XBIGFR_SET_PREC(f, prec);
131         return Fbigfr_get_precision(f);
132 }
133
134 \f
135 Bufbyte *bigfr_to_string(mpfr_t f, int base)
136 {
137         mp_exp_t expt;
138         Bufbyte *str;
139         int len;
140         const int sign = mpfr_sgn(f);
141         const int neg = (sign < 0) ? 1 : 0;
142
143         if (mpfr_inf_p(f)) {
144                 if (sign > 0) {
145                         str = indef_to_string((indef)POS_INFINITY);
146                 } else {
147                         str = indef_to_string((indef)NEG_INFINITY);
148                 }
149                 return str;
150         } else if (mpfr_nan_p(f)) {
151                 str = indef_to_string((indef)NOT_A_NUMBER);
152                 return str;
153         } else {
154                 if (base <= 1)
155                         base = 10;
156
157                 str = (Bufbyte *)mpfr_get_str(NULL, &expt, base, 0, f,
158                                               GMP_RNDN);
159                 len = strlen((char *)str) + 1;  /* Count the null terminator */
160
161                 /* Move digits down to insert a radix point */
162                 if (expt <= 0) {
163                         /* We need room for a radix point and leading zeroes */
164                         const int space = -expt + 2;
165                         xrealloc_array(str, Bufbyte, len + space);
166                         memmove(&str[space + neg], &str[neg], len - neg);
167                         memset(&str[neg], '0', space);
168                         str[neg + 1] = '.';
169                         len += space;
170                 } else if (expt < len) {
171                         /* We just need room for a radix point */
172                         xrealloc_array(str, Bufbyte, len + 1);
173                         memmove(&str[expt + neg + 1],
174                                 &str[expt + neg],
175                                 len - (expt + neg));
176                         str[expt + neg] = '.';
177                         len++;
178                 } else {
179                         /* We need room for trailing zeroes */
180                         xrealloc_array(str, Bufbyte, expt + 1);
181                         memset(&str[len-1], '0', expt+2-len);
182                         str[expt] = '\0';
183                         len = expt + 1;
184                 }
185
186                 return str;
187         }
188 }
189
190 Lisp_Object read_bigfr_string(char *cp)
191 {
192         /* The mpfr version of bigfr_set_string (mpfr_set_str)
193            has the following limitation: if p starts with a '+'
194            sign, it does nothing; i.e., it leaves its bigfloat
195            argument untouched.
196            Therefore, move p past any leading '+' signs. */
197         bigfr bfr;
198         Lisp_Object result;
199
200         bigfr_init_prec(bfr, bigfr_get_default_prec());
201
202         if (*cp == '+')
203                 cp++;
204
205         bigfr_set_string(bfr, (const char*)cp, 0);
206         result = make_bigfr_bfr(bfr);
207
208         bigfr_fini(bfr);
209         return result;
210 }
211
212 #if defined HAVE_MPC && defined WITH_MPC ||     \
213         defined HAVE_PSEUC && defined WITH_PSEUC
214 Lisp_Object read_bigc_string(char *cp)
215 {
216         bigfr bf_re, bf_im;
217         int sign;
218         Lisp_Object result;
219
220         BIGFR_INIT_PREC(bf_re, Qnil);
221         BIGFR_INIT_PREC(bf_im, Qnil);
222
223         /* MPC bigc_set_string has no effect
224          * with initial + sign */
225         if (*cp == '+')
226                 cp++;
227         bigfr_set_string(bf_re, cp, 0);
228
229         if (*cp == '-') {
230                 /* jump over a leading minus */
231                 cp++;
232         }
233                 
234         while ((*cp >= '0' && *cp <= '9') ||
235                (*cp == '.'))
236                 cp++;
237
238         /* read the imaginary part */
239         sign = 0;
240         if (*cp == '+') {
241                 cp++;
242                 sign = 1;
243         }
244         if (*cp == '-') {
245                 cp++;
246                 sign = -1;
247         }
248         if ((*cp == 'i' || *cp == 'I') &&
249             (sign != 0)) {
250                 /* expand +i to +1i and -i to -1i */
251                 bigfr_set_long(bf_im, 1L);
252         } else if (sign == 0) {
253                 /* obviously we did not have a+bi,
254                  * but merely bi
255                  */
256                 bigfr_set(bf_im, bf_re);
257                 bigfr_set_long(bf_re, 0L);
258         } else {
259                 bigfr_set_string(bf_im, cp, 0);
260         }
261
262         if (sign < 0)
263                 bigfr_neg(bf_im, bf_im);
264
265         result = make_bigc_bfr(bf_re, bf_im,
266                                max(bigfr_get_prec(bf_re),
267                                    bigfr_get_prec(bf_im)));
268
269         bigfr_fini(bf_re);
270         bigfr_fini(bf_im);
271         return result;
272 }
273 #endif
274
275 \f
276 /* bigfr ops */
277 static Lisp_Object
278 ent_sum_BIGFR_T(Lisp_Object l, Lisp_Object r)
279 {
280         bigfr_set_prec(ent_scratch_bigfr,
281                        max(XBIGFR_GET_PREC(l), XBIGFR_GET_PREC(r)));
282         bigfr_add(ent_scratch_bigfr, XBIGFR_DATA(l), XBIGFR_DATA(r));
283         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
284 }
285 static Lisp_Object
286 ent_sum_BIGFR_T_INT_T(Lisp_Object l, Lisp_Object r)
287 {
288         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
289         bigfr_set_long(ent_scratch_bigfr, ent_int(r));
290         bigfr_add(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
291         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
292 }
293 static Lisp_Object
294 ent_sum_INT_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
295 {
296         return ent_sum_BIGFR_T_INT_T(r, l);
297 }
298 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
299 static Lisp_Object
300 ent_sum_BIGFR_T_BIGZ_T(Lisp_Object l, Lisp_Object r)
301 {
302         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
303         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(r));
304         bigfr_add(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
305         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
306 }
307 static Lisp_Object
308 ent_sum_BIGZ_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
309 {
310         return ent_sum_BIGFR_T_BIGZ_T(r, l);
311 }
312 #endif
313 #if defined HAVE_MPQ && defined WITH_GMP
314 static Lisp_Object
315 ent_sum_BIGFR_T_BIGQ_T(Lisp_Object l, Lisp_Object r)
316 {
317         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
318         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(r));
319         bigfr_add(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
320         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
321 }
322 static Lisp_Object
323 ent_sum_BIGQ_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
324 {
325         return ent_sum_BIGFR_T_BIGQ_T(r, l);
326 }
327 #endif
328 #if defined HAVE_MPF && defined WITH_GMP
329 static Lisp_Object
330 ent_sum_BIGFR_T_BIGF_T(Lisp_Object l, Lisp_Object r)
331 {
332         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
333         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(r));
334         bigfr_add(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
335         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
336 }
337 static Lisp_Object
338 ent_sum_BIGF_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
339 {
340         return ent_sum_BIGFR_T_BIGF_T(r, l);
341 }
342 #endif
343 #ifdef HAVE_FPFLOAT
344 static Lisp_Object
345 ent_sum_BIGFR_T_FLOAT_T(Lisp_Object l, Lisp_Object r)
346 {
347         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
348         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(r));
349         bigfr_add(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
350         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
351 }
352 static Lisp_Object
353 ent_sum_FLOAT_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
354 {
355         return ent_sum_BIGFR_T_FLOAT_T(r, l);
356 }
357 #endif
358
359
360 static Lisp_Object
361 ent_diff_BIGFR_T(Lisp_Object l, Lisp_Object r)
362 {
363         bigfr_set_prec(ent_scratch_bigfr,
364                        max(XBIGFR_GET_PREC(l), XBIGFR_GET_PREC(r)));
365         bigfr_sub(ent_scratch_bigfr, XBIGFR_DATA(l), XBIGFR_DATA(r));
366         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
367 }
368 static Lisp_Object
369 ent_diff_BIGFR_T_INT_T(Lisp_Object l, Lisp_Object r)
370 {
371         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
372         bigfr_set_long(ent_scratch_bigfr, ent_int(r));
373         bigfr_sub(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
374         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
375 }
376 static Lisp_Object
377 ent_diff_INT_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
378 {
379         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
380         bigfr_set_long(ent_scratch_bigfr, ent_int(l));
381         bigfr_sub(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
382         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
383 }
384 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
385 static Lisp_Object
386 ent_diff_BIGFR_T_BIGZ_T(Lisp_Object l, Lisp_Object r)
387 {
388         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
389         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(r));
390         bigfr_sub(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
391         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
392 }
393 static Lisp_Object
394 ent_diff_BIGZ_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
395 {
396         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
397         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(l));
398         bigfr_sub(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
399         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
400 }
401 #endif
402 #if defined HAVE_MPQ && defined WITH_GMP
403 static Lisp_Object
404 ent_diff_BIGFR_T_BIGQ_T(Lisp_Object l, Lisp_Object r)
405 {
406         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
407         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(r));
408         bigfr_sub(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
409         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
410 }
411 static Lisp_Object
412 ent_diff_BIGQ_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
413 {
414         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
415         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(l));
416         bigfr_sub(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
417         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
418 }
419 #endif
420 #if defined HAVE_MPF && defined WITH_GMP
421 static Lisp_Object
422 ent_diff_BIGFR_T_BIGF_T(Lisp_Object l, Lisp_Object r)
423 {
424         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
425         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(r));
426         bigfr_sub(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
427         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
428 }
429 static Lisp_Object
430 ent_diff_BIGF_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
431 {
432         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
433         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(l));
434         bigfr_sub(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
435         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
436 }
437 #endif
438 #ifdef HAVE_FPFLOAT
439 static Lisp_Object
440 ent_diff_BIGFR_T_FLOAT_T(Lisp_Object l, Lisp_Object r)
441 {
442         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
443         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(r));
444         bigfr_sub(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
445         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
446 }
447 static Lisp_Object
448 ent_diff_FLOAT_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
449 {
450         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
451         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(l));
452         bigfr_sub(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
453         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
454 }
455 #endif
456
457 static Lisp_Object
458 ent_neg_BIGFR_T(Lisp_Object l)
459 {
460         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
461         bigfr_neg(ent_scratch_bigfr, XBIGFR_DATA(l));
462         return make_bigfr_bfr(ent_scratch_bigfr);
463 }
464
465 static Lisp_Object
466 ent_prod_BIGFR_T(Lisp_Object l, Lisp_Object r)
467 {
468         bigfr_set_prec(ent_scratch_bigfr,
469                        max(XBIGFR_GET_PREC(l), XBIGFR_GET_PREC(r)));
470         bigfr_mul(ent_scratch_bigfr, XBIGFR_DATA(l), XBIGFR_DATA(r));
471         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
472 }
473 static Lisp_Object
474 ent_prod_BIGFR_T_INT_T(Lisp_Object l, Lisp_Object r)
475 {
476         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
477         bigfr_set_long(ent_scratch_bigfr, ent_int(r));
478         bigfr_mul(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
479         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
480 }
481 static Lisp_Object
482 ent_prod_INT_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
483 {
484         return ent_prod_BIGFR_T_INT_T(r, l);
485 }
486 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
487 static Lisp_Object
488 ent_prod_BIGFR_T_BIGZ_T(Lisp_Object l, Lisp_Object r)
489 {
490         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
491         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(r));
492         bigfr_mul(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
493         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
494 }
495 static Lisp_Object
496 ent_prod_BIGZ_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
497 {
498         return ent_prod_BIGFR_T_BIGZ_T(r, l);
499 }
500 #endif
501 #if defined HAVE_MPQ && defined WITH_GMP
502 static Lisp_Object
503 ent_prod_BIGFR_T_BIGQ_T(Lisp_Object l, Lisp_Object r)
504 {
505         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
506         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(r));
507         bigfr_mul(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
508         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
509 }
510 static Lisp_Object
511 ent_prod_BIGQ_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
512 {
513         return ent_prod_BIGFR_T_BIGQ_T(r, l);
514 }
515 #endif
516 #if defined HAVE_MPF && defined WITH_GMP
517 static Lisp_Object
518 ent_prod_BIGFR_T_BIGF_T(Lisp_Object l, Lisp_Object r)
519 {
520         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
521         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(r));
522         bigfr_mul(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
523         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
524 }
525 static Lisp_Object
526 ent_prod_BIGF_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
527 {
528         return ent_prod_BIGFR_T_BIGF_T(r, l);
529 }
530 #endif
531 #ifdef HAVE_FPFLOAT
532 static Lisp_Object
533 ent_prod_BIGFR_T_FLOAT_T(Lisp_Object l, Lisp_Object r)
534 {
535         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
536         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(r));
537         bigfr_mul(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
538         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
539 }
540 static Lisp_Object
541 ent_prod_FLOAT_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
542 {
543         return ent_prod_BIGFR_T_FLOAT_T(r, l);
544 }
545 #endif
546
547 static Lisp_Object
548 ent_div_BIGFR_T(Lisp_Object l, Lisp_Object r)
549 {
550         if (bigfr_sign(XBIGFR_DATA(r)) == 0) {
551                 int lsgn = bigfr_sign(XBIGFR_DATA(l));
552                 if (lsgn > 0)
553                         return make_indef(POS_INFINITY);
554                 else if (lsgn < 0)
555                         return make_indef(NEG_INFINITY);
556                 else
557                         return make_indef(NOT_A_NUMBER);
558         }
559         bigfr_set_prec(ent_scratch_bigfr,
560                       max(XBIGFR_GET_PREC(l), XBIGFR_GET_PREC(r)));
561         bigfr_div(ent_scratch_bigfr, XBIGFR_DATA(l), XBIGFR_DATA(r));
562         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
563 }
564 static Lisp_Object
565 ent_div_BIGFR_T_INT_T(Lisp_Object l, Lisp_Object r)
566 {
567         if (ent_int(r) == 0) {
568                 int lsgn = bigfr_sign(XBIGFR_DATA(l));
569                 if (lsgn > 0)
570                         return make_indef(POS_INFINITY);
571                 else if (lsgn < 0)
572                         return make_indef(NEG_INFINITY);
573                 else
574                         return make_indef(NOT_A_NUMBER);
575         }
576
577         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
578         bigfr_set_long(ent_scratch_bigfr, ent_int(r));
579         bigfr_div(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
580         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
581 }
582 static Lisp_Object
583 ent_div_INT_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
584 {
585         if (bigfr_sign(XBIGFR_DATA(r)) == 0) {
586                 EMACS_INT rl = ent_int(l);
587                 if (rl > 0)
588                         return make_indef(POS_INFINITY);
589                 else if (rl < 0)
590                         return make_indef(NEG_INFINITY);
591                 else
592                         return make_indef(NOT_A_NUMBER);
593         }
594
595         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
596         bigfr_set_long(ent_scratch_bigfr, ent_int(l));
597         bigfr_div(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
598         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
599 }
600 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
601 static Lisp_Object
602 ent_div_BIGFR_T_BIGZ_T(Lisp_Object l, Lisp_Object r)
603 {
604         if (bigz_sign(XBIGZ_DATA(r)) == 0) {
605                 int lsgn = bigfr_sign(XBIGFR_DATA(l));
606                 if (lsgn > 0)
607                         return make_indef(POS_INFINITY);
608                 else if (lsgn < 0)
609                         return make_indef(NEG_INFINITY);
610                 else
611                         return make_indef(NOT_A_NUMBER);
612         }
613
614         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
615         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(r));
616         bigfr_div(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
617         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
618 }
619 static Lisp_Object
620 ent_div_BIGZ_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
621 {
622         if (bigfr_sign(XBIGFR_DATA(r)) == 0) {
623                 int lsgn = bigz_sign(XBIGZ_DATA(l));
624                 if (lsgn > 0)
625                         return make_indef(POS_INFINITY);
626                 else if (lsgn < 0)
627                         return make_indef(NEG_INFINITY);
628                 else
629                         return make_indef(NOT_A_NUMBER);
630         }
631
632         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
633         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(l));
634         bigfr_div(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
635         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
636 }
637 #endif
638 #if defined HAVE_MPQ && defined WITH_GMP
639 static Lisp_Object
640 ent_div_BIGFR_T_BIGQ_T(Lisp_Object l, Lisp_Object r)
641 {
642         if (bigq_sign(XBIGQ_DATA(r)) == 0) {
643                 int lsgn = bigfr_sign(XBIGFR_DATA(l));
644                 if (lsgn > 0)
645                         return make_indef(POS_INFINITY);
646                 else if (lsgn < 0)
647                         return make_indef(NEG_INFINITY);
648                 else
649                         return make_indef(NOT_A_NUMBER);
650         }
651
652         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
653         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(r));
654         bigfr_div(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
655         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
656 }
657 static Lisp_Object
658 ent_div_BIGQ_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
659 {
660         if (bigfr_sign(XBIGFR_DATA(r)) == 0) {
661                 int lsgn = bigq_sign(XBIGQ_DATA(l));
662                 if (lsgn > 0)
663                         return make_indef(POS_INFINITY);
664                 else if (lsgn < 0)
665                         return make_indef(NEG_INFINITY);
666                 else
667                         return make_indef(NOT_A_NUMBER);
668         }
669
670         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
671         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(l));
672         bigfr_div(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
673         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
674 }
675 #endif
676 #if defined HAVE_MPF && defined WITH_GMP
677 static Lisp_Object
678 ent_div_BIGFR_T_BIGF_T(Lisp_Object l, Lisp_Object r)
679 {
680         if (bigf_sign(XBIGF_DATA(r)) == 0) {
681                 int lsgn = bigfr_sign(XBIGFR_DATA(l));
682                 if (lsgn > 0)
683                         return make_indef(POS_INFINITY);
684                 else if (lsgn < 0)
685                         return make_indef(NEG_INFINITY);
686                 else
687                         return make_indef(NOT_A_NUMBER);
688         }
689
690         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
691         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(r));
692         bigfr_div(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
693         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
694 }
695 static Lisp_Object
696 ent_div_BIGF_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
697 {
698         if (bigfr_sign(XBIGFR_DATA(r)) == 0) {
699                 int lsgn = bigf_sign(XBIGF_DATA(l));
700                 if (lsgn > 0)
701                         return make_indef(POS_INFINITY);
702                 else if (lsgn < 0)
703                         return make_indef(NEG_INFINITY);
704                 else
705                         return make_indef(NOT_A_NUMBER);
706         }
707
708         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
709         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(l));
710         bigfr_div(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
711         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
712 }
713 #endif
714 #ifdef HAVE_FPFLOAT
715 static Lisp_Object
716 ent_div_BIGFR_T_FLOAT_T(Lisp_Object l, Lisp_Object r)
717 {
718         if (XFLOAT_DATA(r) == 0.0f) {
719                 int lsgn = bigfr_sign(XBIGFR_DATA(l));
720                 if (lsgn > 0)
721                         return make_indef(POS_INFINITY);
722                 else if (lsgn < 0)
723                         return make_indef(NEG_INFINITY);
724                 else
725                         return make_indef(NOT_A_NUMBER);
726         }
727
728         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
729         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(r));
730         bigfr_div(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
731         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
732 }
733 static Lisp_Object
734 ent_div_FLOAT_T_BIGFR_T(Lisp_Object l, Lisp_Object r)
735 {
736         if (bigfr_sign(XBIGFR_DATA(r)) == 0) {
737                 if (XFLOAT_DATA(l) > 0.0f)
738                         return make_indef(POS_INFINITY);
739                 else if (XFLOAT_DATA(r) < 0.0f)
740                         return make_indef(NEG_INFINITY);
741                 else
742                         return make_indef(NOT_A_NUMBER);
743         }
744
745         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
746         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(l));
747         bigfr_div(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
748         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
749 }
750 #endif
751
752 static Lisp_Object
753 ent_inv_BIGFR_T(Lisp_Object r)
754 {
755         if (bigfr_sign(XBIGFR_DATA(r)) == 0) {
756                 return make_indef(POS_INFINITY);
757         }
758         bigfr_set_long(ent_scratch_bigfr, 1L);
759         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(r));
760         bigfr_div(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
761         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
762 }
763 static Lisp_Object
764 ent_rem_BIGFR_T(Lisp_Object unused, Lisp_Object r)
765 {
766         return Qent_mpfr_zero;
767 }
768 static Lisp_Object
769 ent_mod_BIGFR_T(Lisp_Object l, Lisp_Object r)
770 {
771         if (bigfr_sign(XBIGFR_DATA(r)) == 0) {
772                 return Qent_mpfr_zero;
773         }
774         bigfr_set_prec(ent_scratch_bigfr,
775                        max(XBIGFR_GET_PREC(l), XBIGFR_GET_PREC(r)));
776         bigfr_div(ent_scratch_bigfr, XBIGFR_DATA(l), XBIGFR_DATA(r));
777         bigfr_trunc(ent_scratch_bigfr, ent_scratch_bigfr);
778         bigfr_mul(ent_scratch_bigfr, ent_scratch_bigfr, XBIGFR_DATA(r));
779         bigfr_sub(ent_scratch_bigfr, XBIGFR_DATA(l), ent_scratch_bigfr);
780         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
781 }
782 #ifdef bigfr_pow
783 static Lisp_Object
784 ent_pow_BIGFR_T_integer(Lisp_Object l, Lisp_Object r)
785 {
786         EMACS_INT expo = 0;
787
788         if (NILP(Fnonnegativep(r))) {
789                 return ent_unop_inv(
790                         ent_pow_BIGFR_T_integer(l, ent_unop_neg(r)));
791         }
792
793         if (INTP(r)) {
794                 expo = ent_int(r);
795 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
796         } else if (BIGZP(r)) {
797                 if (bigz_fits_long_p(XBIGZ_DATA(r)))
798                         expo = bigz_to_long(XBIGZ_DATA(r));
799                 else
800                         Fsignal(Qarith_error, list1(r));
801 #endif
802         } else {
803                 Fsignal(Qarith_error, list1(r));
804                 return Qnil;
805         }
806
807         bigfr_set_prec(ent_scratch_bigfr, XBIGFR_GET_PREC(l));
808         bigfr_pow(ent_scratch_bigfr, XBIGFR_DATA(l), expo);
809         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
810 }
811 #endif
812
813 /* relations */
814 static inline int
815 ent_lt_bigfr(Lisp_Object l, Lisp_Object r)
816 {
817         return (bigfr_lt(XBIGFR_DATA(l), XBIGFR_DATA(r)));
818 }
819 static inline int
820 ent_lt_bigfr_int(Lisp_Object l, Lisp_Object r)
821 {
822         bigfr_set_long(ent_scratch_bigfr, ent_int(r));
823         return (bigfr_lt(XBIGFR_DATA(l), ent_scratch_bigfr));
824 }
825 static inline int
826 ent_lt_int_bigfr(Lisp_Object l, Lisp_Object r)
827 {
828         bigfr_set_long(ent_scratch_bigfr, ent_int(l));
829         return (bigfr_lt(ent_scratch_bigfr, XBIGFR_DATA(r)));
830 }
831 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
832 static inline int
833 ent_lt_bigfr_bigz(Lisp_Object l, Lisp_Object r)
834 {
835         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(r));
836         return (bigfr_lt(XBIGFR_DATA(l), ent_scratch_bigfr));
837 }
838 static inline int
839 ent_lt_bigz_bigfr(Lisp_Object l, Lisp_Object r)
840 {
841         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(l));
842         return (bigfr_lt(ent_scratch_bigfr, XBIGFR_DATA(r)));
843 }
844 #endif
845 #if defined HAVE_MPQ && defined WITH_GMP
846 static inline int
847 ent_lt_bigfr_bigq(Lisp_Object l, Lisp_Object r)
848 {
849         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(r));
850         return (bigfr_lt(XBIGFR_DATA(l), ent_scratch_bigfr));
851 }
852 static inline int
853 ent_lt_bigq_bigfr(Lisp_Object l, Lisp_Object r)
854 {
855         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(l));
856         return (bigfr_lt(ent_scratch_bigfr, XBIGFR_DATA(r)));
857 }
858 #endif
859 #if defined HAVE_MPF && defined WITH_GMP
860 static inline int
861 ent_lt_bigfr_bigf(Lisp_Object l, Lisp_Object r)
862 {
863         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(r));
864         return (bigfr_lt(XBIGFR_DATA(l), ent_scratch_bigfr));
865 }
866 static inline int
867 ent_lt_bigf_bigfr(Lisp_Object l, Lisp_Object r)
868 {
869         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(l));
870         return (bigfr_lt(ent_scratch_bigfr, XBIGFR_DATA(r)));
871 }
872 #endif
873 #ifdef HAVE_FPFLOAT
874 static inline int
875 ent_lt_bigfr_fpfloat(Lisp_Object l, Lisp_Object r)
876 {
877         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(r));
878         return (bigfr_lt(XBIGFR_DATA(l), ent_scratch_bigfr));
879 }
880 static inline int
881 ent_lt_fpfloat_bigfr(Lisp_Object l, Lisp_Object r)
882 {
883         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(l));
884         return (bigfr_lt(ent_scratch_bigfr, XBIGFR_DATA(r)));
885 }
886 #endif
887
888 static inline int
889 ent_gt_bigfr(Lisp_Object l, Lisp_Object r)
890 {
891         return (bigfr_gt(XBIGFR_DATA(l), XBIGFR_DATA(r)));
892 }
893 static inline int
894 ent_gt_bigfr_int(Lisp_Object l, Lisp_Object r)
895 {
896         bigfr_set_long(ent_scratch_bigfr, ent_int(r));
897         return (bigfr_gt(XBIGFR_DATA(l), ent_scratch_bigfr));
898 }
899 static inline int
900 ent_gt_int_bigfr(Lisp_Object l, Lisp_Object r)
901 {
902         bigfr_set_long(ent_scratch_bigfr, ent_int(l));
903         return (bigfr_gt(ent_scratch_bigfr, XBIGFR_DATA(r)));
904 }
905 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
906 static inline int
907 ent_gt_bigfr_bigz(Lisp_Object l, Lisp_Object r)
908 {
909         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(r));
910         return (bigfr_gt(XBIGFR_DATA(l), ent_scratch_bigfr));
911 }
912 static inline int
913 ent_gt_bigz_bigfr(Lisp_Object l, Lisp_Object r)
914 {
915         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(l));
916         return (bigfr_gt(ent_scratch_bigfr, XBIGFR_DATA(r)));
917 }
918 #endif
919 #if defined HAVE_MPQ && defined WITH_GMP
920 static inline int
921 ent_gt_bigfr_bigq(Lisp_Object l, Lisp_Object r)
922 {
923         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(r));
924         return (bigfr_gt(XBIGFR_DATA(l), ent_scratch_bigfr));
925 }
926 static inline int
927 ent_gt_bigq_bigfr(Lisp_Object l, Lisp_Object r)
928 {
929         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(l));
930         return (bigfr_gt(ent_scratch_bigfr, XBIGFR_DATA(r)));
931 }
932 #endif
933 #if defined HAVE_MPF && defined WITH_GMP
934 static inline int
935 ent_gt_bigfr_bigf(Lisp_Object l, Lisp_Object r)
936 {
937         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(r));
938         return (bigfr_gt(XBIGFR_DATA(l), ent_scratch_bigfr));
939 }
940 static inline int
941 ent_gt_bigf_bigfr(Lisp_Object l, Lisp_Object r)
942 {
943         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(l));
944         return (bigfr_gt(ent_scratch_bigfr, XBIGFR_DATA(r)));
945 }
946 #endif
947 #ifdef HAVE_FPFLOAT
948 static inline int
949 ent_gt_bigfr_fpfloat(Lisp_Object l, Lisp_Object r)
950 {
951         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(r));
952         return (bigfr_gt(XBIGFR_DATA(l), ent_scratch_bigfr));
953 }
954 static inline int
955 ent_gt_fpfloat_bigfr(Lisp_Object l, Lisp_Object r)
956 {
957         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(l));
958         return (bigfr_gt(ent_scratch_bigfr, XBIGFR_DATA(r)));
959 }
960 #endif
961
962 static inline int
963 ent_eq_bigfr(Lisp_Object l, Lisp_Object r)
964 {
965         return (bigfr_eq(XBIGFR_DATA(l), XBIGFR_DATA(r)));
966 }
967 static inline int
968 ent_eq_bigfr_int(Lisp_Object l, Lisp_Object r)
969 {
970         bigfr_set_long(ent_scratch_bigfr, ent_int(r));
971         return (bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
972 }
973 static inline int
974 ent_eq_int_bigfr(Lisp_Object l, Lisp_Object r)
975 {
976         bigfr_set_long(ent_scratch_bigfr, ent_int(l));
977         return (bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
978 }
979 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
980 static inline int
981 ent_eq_bigfr_bigz(Lisp_Object l, Lisp_Object r)
982 {
983         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(r));
984         return (bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
985 }
986 static inline int
987 ent_eq_bigz_bigfr(Lisp_Object l, Lisp_Object r)
988 {
989         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(l));
990         return (bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
991 }
992 #endif
993 #if defined HAVE_MPQ && defined WITH_GMP
994 static inline int
995 ent_eq_bigfr_bigq(Lisp_Object l, Lisp_Object r)
996 {
997         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(r));
998         return (bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
999 }
1000 static inline int
1001 ent_eq_bigq_bigfr(Lisp_Object l, Lisp_Object r)
1002 {
1003         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(l));
1004         return (bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
1005 }
1006 #endif
1007 #if defined HAVE_MPF && defined WITH_GMP
1008 static inline int
1009 ent_eq_bigfr_bigf(Lisp_Object l, Lisp_Object r)
1010 {
1011         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(r));
1012         return (bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
1013 }
1014 static inline int
1015 ent_eq_bigf_bigfr(Lisp_Object l, Lisp_Object r)
1016 {
1017         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(l));
1018         return (bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
1019 }
1020 #endif
1021 #ifdef HAVE_FPFLOAT
1022 static inline int
1023 ent_eq_bigfr_fpfloat(Lisp_Object l, Lisp_Object r)
1024 {
1025         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(r));
1026         return (bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
1027 }
1028 static inline int
1029 ent_eq_fpfloat_bigfr(Lisp_Object l, Lisp_Object r)
1030 {
1031         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(l));
1032         return (bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
1033 }
1034 #endif
1035
1036 static inline int
1037 ent_ne_bigfr(Lisp_Object l, Lisp_Object r)
1038 {
1039         return !(bigfr_eq(XBIGFR_DATA(l), XBIGFR_DATA(r)));
1040 }
1041 static inline int
1042 ent_ne_bigfr_int(Lisp_Object l, Lisp_Object r)
1043 {
1044         bigfr_set_long(ent_scratch_bigfr, ent_int(r));
1045         return !(bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
1046 }
1047 static inline int
1048 ent_ne_int_bigfr(Lisp_Object l, Lisp_Object r)
1049 {
1050         bigfr_set_long(ent_scratch_bigfr, ent_int(l));
1051         return !(bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
1052 }
1053 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1054 static inline int
1055 ent_ne_bigfr_bigz(Lisp_Object l, Lisp_Object r)
1056 {
1057         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(r));
1058         return !(bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
1059 }
1060 static inline int
1061 ent_ne_bigz_bigfr(Lisp_Object l, Lisp_Object r)
1062 {
1063         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(l));
1064         return !(bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
1065 }
1066 #endif
1067 #if defined HAVE_MPQ && defined WITH_GMP
1068 static inline int
1069 ent_ne_bigfr_bigq(Lisp_Object l, Lisp_Object r)
1070 {
1071         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(r));
1072         return !(bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
1073 }
1074 static inline int
1075 ent_ne_bigq_bigfr(Lisp_Object l, Lisp_Object r)
1076 {
1077         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(l));
1078         return !(bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
1079 }
1080 #endif
1081 #if defined HAVE_MPF && defined WITH_GMP
1082 static inline int
1083 ent_ne_bigfr_bigf(Lisp_Object l, Lisp_Object r)
1084 {
1085         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(r));
1086         return !(bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
1087 }
1088 static inline int
1089 ent_ne_bigf_bigfr(Lisp_Object l, Lisp_Object r)
1090 {
1091         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(l));
1092         return !(bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
1093 }
1094 #endif
1095 #ifdef HAVE_FPFLOAT
1096 static inline int
1097 ent_ne_bigfr_fpfloat(Lisp_Object l, Lisp_Object r)
1098 {
1099         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(r));
1100         return !(bigfr_eq(XBIGFR_DATA(l), ent_scratch_bigfr));
1101 }
1102 static inline int
1103 ent_ne_fpfloat_bigfr(Lisp_Object l, Lisp_Object r)
1104 {
1105         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(l));
1106         return !(bigfr_eq(ent_scratch_bigfr, XBIGFR_DATA(r)));
1107 }
1108 #endif
1109
1110 \f
1111 static inline Lisp_Object
1112 _ent_lift_INT_T_BIGFR_T(Lisp_Object number, ent_lift_args_t la)
1113 {
1114         unsigned long precision = la->precision;
1115         return make_bigfr(ent_int(number), precision);
1116 }
1117
1118 static inline Lisp_Object
1119 _ent_lift_BIGFR_T_INT_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
1120 {
1121         return make_int(bigfr_to_long(XBIGFR_DATA(number)));
1122 }
1123
1124 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1125 static inline Lisp_Object
1126 _ent_lift_BIGZ_T_BIGFR_T(Lisp_Object number, ent_lift_args_t la)
1127 {
1128         unsigned long precision = la->precision;
1129
1130         bigfr_set_prec(ent_scratch_bigfr, precision);
1131         bigfr_set_bigz(ent_scratch_bigfr, XBIGZ_DATA(number));
1132         return make_bigfr_bfr(ent_scratch_bigfr);
1133 }
1134
1135 static inline Lisp_Object
1136 _ent_lift_BIGFR_T_BIGZ_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
1137 {
1138         bigz_set_bigfr(ent_scratch_bigz, XBIGFR_DATA(number));
1139         return make_bigz_bz(ent_scratch_bigz);
1140 }
1141 #endif  /* HAVE_MPZ */
1142
1143 #if defined HAVE_MPQ && defined WITH_GMP
1144 static inline Lisp_Object
1145 _ent_lift_BIGQ_T_BIGFR_T(Lisp_Object number, ent_lift_args_t la)
1146 {
1147         unsigned long precision = la->precision;
1148
1149         bigfr_set_prec(ent_scratch_bigfr, precision);
1150         bigfr_set_bigq(ent_scratch_bigfr, XBIGQ_DATA(number));
1151         return make_bigfr_bfr(ent_scratch_bigfr);
1152 }
1153 #endif  /* HAVE_MPQ */
1154
1155 #if defined HAVE_MPF && defined WITH_GMP
1156 static inline Lisp_Object
1157 _ent_lift_BIGF_T_BIGFR_T(Lisp_Object number, ent_lift_args_t la)
1158 {
1159         unsigned long precision = la->precision;
1160
1161         bigfr_set_prec(ent_scratch_bigfr, precision);
1162         bigfr_set_bigf(ent_scratch_bigfr, XBIGF_DATA(number));
1163         return make_bigfr_bfr(ent_scratch_bigfr);
1164 }
1165
1166 static inline Lisp_Object
1167 _ent_lift_BIGFR_T_BIGF_T(Lisp_Object number, ent_lift_args_t la)
1168 {
1169         unsigned long precision = la->precision;
1170
1171         bigf_set_prec(ent_scratch_bigf, precision);
1172         bigf_set_bigfr(ent_scratch_bigf, XBIGFR_DATA(number));
1173         return make_bigf_bf(ent_scratch_bigf);
1174 }
1175 #endif  /* HAVE_MPF */
1176
1177 #ifdef HAVE_FPFLOAT
1178 static inline Lisp_Object
1179 _ent_lift_FLOAT_T_BIGFR_T(Lisp_Object number, ent_lift_args_t la)
1180 {
1181         unsigned long precision = la->precision;
1182
1183         bigfr_set_prec(ent_scratch_bigfr, precision);
1184         bigfr_set_fpfloat(ent_scratch_bigfr, XFLOAT_DATA(number));
1185         return make_bigfr_bfr(ent_scratch_bigfr);
1186 }
1187
1188 static inline Lisp_Object
1189 _ent_lift_BIGFR_T_FLOAT_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
1190 {
1191         return make_float(bigfr_to_fpfloat(XBIGFR_DATA(number)));
1192 }
1193 #endif
1194
1195 static inline Lisp_Object
1196 _ent_lift_BIGFR_T_BIGFR_T(Lisp_Object number, ent_lift_args_t la)
1197 {
1198         unsigned long precision = la->precision;
1199
1200         bigfr_set_prec(ent_scratch_bigfr, precision);
1201         bigfr_set(ent_scratch_bigfr, XBIGFR_DATA(number));
1202         return ent_mpfr_wipe_indef(ent_scratch_bigfr);
1203 }
1204
1205 static inline int
1206 ent_mpfr_zerop(Lisp_Object l)
1207 {
1208         return (bigfr_sign(XBIGFR_DATA(l)) == 0);
1209 }
1210
1211 static inline int
1212 ent_mpfr_onep(Lisp_Object l)
1213 {
1214         return (bigfr_to_fpfloat(XBIGFR_DATA(l)) == 1.0f);
1215 }
1216
1217 static inline int
1218 ent_mpfr_unitp(Lisp_Object unused)
1219 {
1220         return 1;
1221 }
1222
1223 \f
1224 static inline void
1225 ent_mpfr_nullary_optable_init(void)
1226 {
1227         Qent_mpfr_zero = make_bigfr(0.0f, internal_get_precision(Qnil));
1228         Qent_mpfr_one = make_bigfr(1.0f, internal_get_precision(Qnil));
1229         staticpro(&Qent_mpfr_zero);
1230         staticpro(&Qent_mpfr_one);
1231
1232         ent_nullop_register(ASE_NULLARY_OP_ZERO, BIGFR_T, Qent_mpfr_zero);
1233         ent_nullop_register(ASE_NULLARY_OP_ONE, BIGFR_T, Qent_mpfr_one);
1234 }
1235
1236 static inline void
1237 ent_mpfr_unary_optable_init(void)
1238 {
1239         ent_unop_register(ASE_UNARY_OP_NEG, BIGFR_T, ent_neg_BIGFR_T);
1240         ent_unop_register(ASE_UNARY_OP_INV, BIGFR_T, ent_inv_BIGFR_T);
1241 }
1242
1243 static inline void
1244 ent_mpfr_binary_optable_init(void)
1245 {
1246         /* sums */
1247         ent_binop_register(ASE_BINARY_OP_SUM,
1248                            BIGFR_T, BIGFR_T, ent_sum_BIGFR_T);
1249         ent_binop_register(ASE_BINARY_OP_SUM,
1250                            BIGFR_T, INT_T, ent_sum_BIGFR_T_INT_T);
1251         ent_binop_register(ASE_BINARY_OP_SUM,
1252                            INT_T, BIGFR_T, ent_sum_INT_T_BIGFR_T);
1253 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1254         ent_binop_register(ASE_BINARY_OP_SUM,
1255                            BIGFR_T, BIGZ_T, ent_sum_BIGFR_T_BIGZ_T);
1256         ent_binop_register(ASE_BINARY_OP_SUM,
1257                            BIGZ_T, BIGFR_T, ent_sum_BIGZ_T_BIGFR_T);
1258 #endif
1259 #if defined HAVE_MPQ && defined WITH_GMP
1260         ent_binop_register(ASE_BINARY_OP_SUM,
1261                            BIGFR_T, BIGQ_T, ent_sum_BIGFR_T_BIGQ_T);
1262         ent_binop_register(ASE_BINARY_OP_SUM,
1263                            BIGQ_T, BIGFR_T, ent_sum_BIGQ_T_BIGFR_T);
1264 #endif
1265 #if defined HAVE_MPF && defined WITH_GMP
1266         ent_binop_register(ASE_BINARY_OP_SUM,
1267                            BIGFR_T, BIGF_T, ent_sum_BIGFR_T_BIGF_T);
1268         ent_binop_register(ASE_BINARY_OP_SUM,
1269                            BIGF_T, BIGFR_T, ent_sum_BIGF_T_BIGFR_T);
1270 #endif
1271 #ifdef HAVE_FPFLOAT
1272         ent_binop_register(ASE_BINARY_OP_SUM,
1273                            FLOAT_T, BIGFR_T, ent_sum_FLOAT_T_BIGFR_T);
1274         ent_binop_register(ASE_BINARY_OP_SUM,
1275                            BIGFR_T, FLOAT_T, ent_sum_BIGFR_T_FLOAT_T);
1276 #endif
1277
1278         ent_binop_register(ASE_BINARY_OP_DIFF,
1279                            BIGFR_T, BIGFR_T, ent_diff_BIGFR_T);
1280         ent_binop_register(ASE_BINARY_OP_DIFF,
1281                            BIGFR_T, INT_T, ent_diff_BIGFR_T_INT_T);
1282         ent_binop_register(ASE_BINARY_OP_DIFF,
1283                            INT_T, BIGFR_T, ent_diff_INT_T_BIGFR_T);
1284 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1285         ent_binop_register(ASE_BINARY_OP_DIFF,
1286                            BIGFR_T, BIGZ_T, ent_diff_BIGFR_T_BIGZ_T);
1287         ent_binop_register(ASE_BINARY_OP_DIFF,
1288                            BIGZ_T, BIGFR_T, ent_diff_BIGZ_T_BIGFR_T);
1289 #endif
1290 #if defined HAVE_MPQ && defined WITH_GMP
1291         ent_binop_register(ASE_BINARY_OP_DIFF,
1292                            BIGFR_T, BIGQ_T, ent_diff_BIGFR_T_BIGQ_T);
1293         ent_binop_register(ASE_BINARY_OP_DIFF,
1294                            BIGQ_T, BIGFR_T, ent_diff_BIGQ_T_BIGFR_T);
1295 #endif
1296 #if defined HAVE_MPF && defined WITH_GMP
1297         ent_binop_register(ASE_BINARY_OP_DIFF,
1298                            BIGFR_T, BIGF_T, ent_diff_BIGFR_T_BIGF_T);
1299         ent_binop_register(ASE_BINARY_OP_DIFF,
1300                            BIGF_T, BIGFR_T, ent_diff_BIGF_T_BIGFR_T);
1301 #endif
1302 #ifdef HAVE_FPFLOAT
1303         ent_binop_register(ASE_BINARY_OP_DIFF,
1304                            FLOAT_T, BIGFR_T, ent_diff_FLOAT_T_BIGFR_T);
1305         ent_binop_register(ASE_BINARY_OP_DIFF,
1306                            BIGFR_T, FLOAT_T, ent_diff_BIGFR_T_FLOAT_T);
1307 #endif
1308
1309         /* products */
1310         ent_binop_register(ASE_BINARY_OP_PROD,
1311                            BIGFR_T, BIGFR_T, ent_prod_BIGFR_T);
1312         ent_binop_register(ASE_BINARY_OP_PROD,
1313                            BIGFR_T, INT_T, ent_prod_BIGFR_T_INT_T);
1314         ent_binop_register(ASE_BINARY_OP_PROD,
1315                            INT_T, BIGFR_T, ent_prod_INT_T_BIGFR_T);
1316 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1317         ent_binop_register(ASE_BINARY_OP_PROD,
1318                            BIGFR_T, BIGZ_T, ent_prod_BIGFR_T_BIGZ_T);
1319         ent_binop_register(ASE_BINARY_OP_PROD,
1320                            BIGZ_T, BIGFR_T, ent_prod_BIGZ_T_BIGFR_T);
1321 #endif
1322 #if defined HAVE_MPQ && defined WITH_GMP
1323         ent_binop_register(ASE_BINARY_OP_PROD,
1324                            BIGFR_T, BIGQ_T, ent_prod_BIGFR_T_BIGQ_T);
1325         ent_binop_register(ASE_BINARY_OP_PROD,
1326                            BIGQ_T, BIGFR_T, ent_prod_BIGQ_T_BIGFR_T);
1327 #endif
1328 #if defined HAVE_MPF && defined WITH_GMP
1329         ent_binop_register(ASE_BINARY_OP_PROD,
1330                            BIGFR_T, BIGF_T, ent_prod_BIGFR_T_BIGF_T);
1331         ent_binop_register(ASE_BINARY_OP_PROD,
1332                            BIGF_T, BIGFR_T, ent_prod_BIGF_T_BIGFR_T);
1333 #endif
1334 #ifdef HAVE_FPFLOAT
1335         ent_binop_register(ASE_BINARY_OP_PROD,
1336                            FLOAT_T, BIGFR_T, ent_prod_FLOAT_T_BIGFR_T);
1337         ent_binop_register(ASE_BINARY_OP_PROD,
1338                            BIGFR_T, FLOAT_T, ent_prod_BIGFR_T_FLOAT_T);
1339 #endif
1340
1341         ent_binop_register(ASE_BINARY_OP_DIV,
1342                            BIGFR_T, BIGFR_T, ent_div_BIGFR_T);
1343         ent_binop_register(ASE_BINARY_OP_DIV,
1344                            BIGFR_T, INT_T, ent_div_BIGFR_T_INT_T);
1345         ent_binop_register(ASE_BINARY_OP_DIV,
1346                            INT_T, BIGFR_T, ent_div_INT_T_BIGFR_T);
1347 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1348         ent_binop_register(ASE_BINARY_OP_DIV,
1349                            BIGFR_T, BIGZ_T, ent_div_BIGFR_T_BIGZ_T);
1350         ent_binop_register(ASE_BINARY_OP_DIV,
1351                            BIGZ_T, BIGFR_T, ent_div_BIGZ_T_BIGFR_T);
1352 #endif
1353 #if defined HAVE_MPQ && defined WITH_GMP
1354         ent_binop_register(ASE_BINARY_OP_DIV,
1355                            BIGFR_T, BIGQ_T, ent_div_BIGFR_T_BIGQ_T);
1356         ent_binop_register(ASE_BINARY_OP_DIV,
1357                            BIGQ_T, BIGFR_T, ent_div_BIGQ_T_BIGFR_T);
1358 #endif
1359 #if defined HAVE_MPF && defined WITH_GMP
1360         ent_binop_register(ASE_BINARY_OP_DIV,
1361                            BIGFR_T, BIGF_T, ent_div_BIGFR_T_BIGF_T);
1362         ent_binop_register(ASE_BINARY_OP_DIV,
1363                            BIGF_T, BIGFR_T, ent_div_BIGF_T_BIGFR_T);
1364 #endif
1365 #ifdef HAVE_FPFLOAT
1366         ent_binop_register(ASE_BINARY_OP_DIV,
1367                            FLOAT_T, BIGFR_T, ent_div_FLOAT_T_BIGFR_T);
1368         ent_binop_register(ASE_BINARY_OP_DIV,
1369                            BIGFR_T, FLOAT_T, ent_div_BIGFR_T_FLOAT_T);
1370 #endif
1371
1372         ent_binop_register(ASE_BINARY_OP_QUO,
1373                            BIGFR_T, BIGFR_T, ent_div_BIGFR_T);
1374         ent_binop_register(ASE_BINARY_OP_QUO,
1375                            BIGFR_T, INT_T, ent_div_BIGFR_T_INT_T);
1376         ent_binop_register(ASE_BINARY_OP_QUO,
1377                            INT_T, BIGFR_T, ent_div_INT_T_BIGFR_T);
1378 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1379         ent_binop_register(ASE_BINARY_OP_QUO,
1380                            BIGFR_T, BIGZ_T, ent_div_BIGFR_T_BIGZ_T);
1381         ent_binop_register(ASE_BINARY_OP_QUO,
1382                            BIGZ_T, BIGFR_T, ent_div_BIGZ_T_BIGFR_T);
1383 #endif
1384 #if defined HAVE_MPQ && defined WITH_GMP
1385         ent_binop_register(ASE_BINARY_OP_QUO,
1386                            BIGFR_T, BIGQ_T, ent_div_BIGFR_T_BIGQ_T);
1387         ent_binop_register(ASE_BINARY_OP_QUO,
1388                            BIGQ_T, BIGFR_T, ent_div_BIGQ_T_BIGFR_T);
1389 #endif
1390 #if defined HAVE_MPF && defined WITH_GMP
1391         ent_binop_register(ASE_BINARY_OP_QUO,
1392                            BIGFR_T, BIGF_T, ent_div_BIGFR_T_BIGF_T);
1393         ent_binop_register(ASE_BINARY_OP_QUO,
1394                            BIGF_T, BIGFR_T, ent_div_BIGF_T_BIGFR_T);
1395 #endif
1396 #ifdef HAVE_FPFLOAT
1397         ent_binop_register(ASE_BINARY_OP_QUO,
1398                            FLOAT_T, BIGFR_T, ent_div_FLOAT_T_BIGFR_T);
1399         ent_binop_register(ASE_BINARY_OP_QUO,
1400                            BIGFR_T, FLOAT_T, ent_div_BIGFR_T_FLOAT_T);
1401 #endif
1402
1403         /* remainders */
1404         ent_binop_register(ASE_BINARY_OP_MOD,
1405                            BIGFR_T, BIGFR_T, ent_mod_BIGFR_T);
1406         ent_binop_register(ASE_BINARY_OP_REM,
1407                            BIGFR_T, BIGFR_T, ent_rem_BIGFR_T);
1408         ent_binop_register(ASE_BINARY_OP_REM,
1409                            INT_T, BIGFR_T, ent_rem_BIGFR_T);
1410         ent_binop_register(ASE_BINARY_OP_REM,
1411                            INDEF_T, BIGFR_T, ent_rem_BIGFR_T);
1412 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1413         ent_binop_register(ASE_BINARY_OP_REM,
1414                            BIGZ_T, BIGFR_T, ent_rem_BIGFR_T);
1415 #endif
1416 #if defined HAVE_MPQ && defined WITH_GMP
1417         ent_binop_register(ASE_BINARY_OP_REM,
1418                            BIGQ_T, BIGFR_T, ent_rem_BIGFR_T);
1419 #endif
1420 #if defined HAVE_MPF && defined WITH_GMP
1421         ent_binop_register(ASE_BINARY_OP_REM,
1422                            BIGF_T, BIGFR_T, ent_rem_BIGFR_T);
1423 #endif
1424 #if HAVE_FPFLOAT
1425         ent_binop_register(ASE_BINARY_OP_REM,
1426                            FLOAT_T, BIGFR_T, ent_rem_BIGFR_T);
1427 #endif
1428
1429 #ifdef bigfr_pow
1430         ent_binop_register(ASE_BINARY_OP_POW,
1431                            BIGFR_T, INT_T, ent_pow_BIGFR_T_integer);
1432 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1433         ent_binop_register(ASE_BINARY_OP_POW,
1434                            BIGFR_T, BIGZ_T, ent_pow_BIGFR_T_integer);
1435 #endif
1436 #endif
1437 }
1438
1439 static inline void
1440 ent_mpfr_unary_reltable_init(void)
1441 {
1442         ent_unrel_register(ASE_UNARY_REL_ZEROP, BIGFR_T, ent_mpfr_zerop);
1443         ent_unrel_register(ASE_UNARY_REL_ONEP, BIGFR_T, ent_mpfr_onep);
1444         ent_unrel_register(ASE_UNARY_REL_UNITP, BIGFR_T, ent_mpfr_unitp);
1445 }
1446
1447 static inline void
1448 ent_mpfr_binary_reltable_init(void)
1449 {
1450         ent_binrel_register(ASE_BINARY_REL_LESSP,
1451                             BIGFR_T, BIGFR_T, ent_lt_bigfr);
1452         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1453                             BIGFR_T, BIGFR_T, ent_gt_bigfr);
1454         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1455                             BIGFR_T, BIGFR_T, ent_eq_bigfr);
1456         ent_binrel_register(ASE_BINARY_REL_NEQP,
1457                             BIGFR_T, BIGFR_T, ent_ne_bigfr);
1458
1459         ent_binrel_register(ASE_BINARY_REL_LESSP,
1460                             BIGFR_T, INT_T, ent_lt_bigfr_int);
1461         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1462                             BIGFR_T, INT_T, ent_gt_bigfr_int);
1463         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1464                             BIGFR_T, INT_T, ent_eq_bigfr_int);
1465         ent_binrel_register(ASE_BINARY_REL_NEQP,
1466                             BIGFR_T, INT_T, ent_ne_bigfr_int);
1467
1468         ent_binrel_register(ASE_BINARY_REL_LESSP,
1469                             INT_T, BIGFR_T, ent_lt_int_bigfr);
1470         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1471                             INT_T, BIGFR_T, ent_gt_int_bigfr);
1472         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1473                             INT_T, BIGFR_T, ent_eq_int_bigfr);
1474         ent_binrel_register(ASE_BINARY_REL_NEQP,
1475                             INT_T, BIGFR_T, ent_ne_int_bigfr);
1476
1477 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1478         ent_binrel_register(ASE_BINARY_REL_LESSP,
1479                             BIGFR_T, BIGZ_T, ent_lt_bigfr_bigz);
1480         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1481                             BIGFR_T, BIGZ_T, ent_gt_bigfr_bigz);
1482         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1483                             BIGFR_T, BIGZ_T, ent_eq_bigfr_bigz);
1484         ent_binrel_register(ASE_BINARY_REL_NEQP,
1485                             BIGFR_T, BIGZ_T, ent_ne_bigfr_bigz);
1486
1487         ent_binrel_register(ASE_BINARY_REL_LESSP,
1488                             BIGZ_T, BIGFR_T, ent_lt_bigz_bigfr);
1489         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1490                             BIGZ_T, BIGFR_T, ent_gt_bigz_bigfr);
1491         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1492                             BIGZ_T, BIGFR_T, ent_eq_bigz_bigfr);
1493         ent_binrel_register(ASE_BINARY_REL_NEQP,
1494                             BIGZ_T, BIGFR_T, ent_ne_bigz_bigfr);
1495 #endif
1496 #if defined HAVE_MPQ && defined WITH_GMP
1497         ent_binrel_register(ASE_BINARY_REL_LESSP,
1498                             BIGFR_T, BIGQ_T, ent_lt_bigfr_bigq);
1499         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1500                             BIGFR_T, BIGQ_T, ent_gt_bigfr_bigq);
1501         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1502                             BIGFR_T, BIGQ_T, ent_eq_bigfr_bigq);
1503         ent_binrel_register(ASE_BINARY_REL_NEQP,
1504                             BIGFR_T, BIGQ_T, ent_ne_bigfr_bigq);
1505
1506         ent_binrel_register(ASE_BINARY_REL_LESSP,
1507                             BIGQ_T, BIGFR_T, ent_lt_bigq_bigfr);
1508         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1509                             BIGQ_T, BIGFR_T, ent_gt_bigq_bigfr);
1510         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1511                             BIGQ_T, BIGFR_T, ent_eq_bigq_bigfr);
1512         ent_binrel_register(ASE_BINARY_REL_NEQP,
1513                             BIGQ_T, BIGFR_T, ent_ne_bigq_bigfr);
1514 #endif
1515 #if defined HAVE_MPF && defined WITH_GMP
1516         ent_binrel_register(ASE_BINARY_REL_LESSP,
1517                             BIGFR_T, BIGF_T, ent_lt_bigfr_bigf);
1518         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1519                             BIGFR_T, BIGF_T, ent_gt_bigfr_bigf);
1520         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1521                             BIGFR_T, BIGF_T, ent_eq_bigfr_bigf);
1522         ent_binrel_register(ASE_BINARY_REL_NEQP,
1523                             BIGFR_T, BIGF_T, ent_ne_bigfr_bigf);
1524
1525         ent_binrel_register(ASE_BINARY_REL_LESSP,
1526                             BIGF_T, BIGFR_T, ent_lt_bigf_bigfr);
1527         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1528                             BIGF_T, BIGFR_T, ent_gt_bigf_bigfr);
1529         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1530                             BIGF_T, BIGFR_T, ent_eq_bigf_bigfr);
1531         ent_binrel_register(ASE_BINARY_REL_NEQP,
1532                             BIGF_T, BIGFR_T, ent_ne_bigf_bigfr);
1533 #endif
1534 #ifdef HAVE_FPFLOAT
1535         ent_binrel_register(ASE_BINARY_REL_LESSP,
1536                             BIGFR_T, FLOAT_T, ent_lt_bigfr_fpfloat);
1537         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1538                             BIGFR_T, FLOAT_T, ent_gt_bigfr_fpfloat);
1539         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1540                             BIGFR_T, FLOAT_T, ent_eq_bigfr_fpfloat);
1541         ent_binrel_register(ASE_BINARY_REL_NEQP,
1542                             BIGFR_T, FLOAT_T, ent_ne_bigfr_fpfloat);
1543
1544         ent_binrel_register(ASE_BINARY_REL_LESSP,
1545                             FLOAT_T, BIGFR_T, ent_lt_fpfloat_bigfr);
1546         ent_binrel_register(ASE_BINARY_REL_GREATERP,
1547                             FLOAT_T, BIGFR_T, ent_gt_fpfloat_bigfr);
1548         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1549                             FLOAT_T, BIGFR_T, ent_eq_fpfloat_bigfr);
1550         ent_binrel_register(ASE_BINARY_REL_NEQP,
1551                             FLOAT_T, BIGFR_T, ent_ne_fpfloat_bigfr);
1552 #endif
1553 }
1554
1555 static inline void
1556 ent_mpfr_lifttable_init(void)
1557 {
1558         ent_lift_register(BIGFR_T, BIGFR_T, _ent_lift_BIGFR_T_BIGFR_T);
1559         ent_lift_register(BIGFR_T, INT_T, _ent_lift_BIGFR_T_INT_T);
1560         ent_lift_register(INT_T, BIGFR_T, _ent_lift_INT_T_BIGFR_T);
1561 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1562         ent_lift_register(BIGFR_T, BIGZ_T, _ent_lift_BIGFR_T_BIGZ_T);
1563         ent_lift_register(BIGZ_T, BIGFR_T, _ent_lift_BIGZ_T_BIGFR_T);
1564 #endif
1565 #if defined HAVE_MPQ && defined WITH_GMP
1566         ent_lift_register(BIGQ_T, BIGFR_T, _ent_lift_BIGQ_T_BIGFR_T);
1567 #endif
1568 #if defined HAVE_MPF && defined WITH_GMP
1569         ent_lift_register(BIGFR_T, BIGF_T, _ent_lift_BIGFR_T_BIGF_T);
1570         ent_lift_register(BIGF_T, BIGFR_T, _ent_lift_BIGF_T_BIGFR_T);
1571 #endif
1572 #ifdef HAVE_FPFLOAT
1573         ent_lift_register(BIGFR_T, FLOAT_T, _ent_lift_BIGFR_T_FLOAT_T);
1574         ent_lift_register(FLOAT_T, BIGFR_T, _ent_lift_FLOAT_T_BIGFR_T);
1575 #endif
1576         ent_lift_register(INDEF_T, BIGFR_T, ent_lift_INDEF_T_COMPARABLE);
1577 }
1578
1579 \f
1580 void init_optables_BIGFR_T(void)
1581 {
1582         ent_mpfr_nullary_optable_init();
1583         ent_mpfr_unary_optable_init();
1584         ent_mpfr_binary_optable_init();
1585         ent_mpfr_unary_reltable_init();
1586         ent_mpfr_binary_reltable_init();
1587         ent_mpfr_lifttable_init();
1588 }
1589
1590 void init_ent_mpfr(void)
1591 {
1592         bigfr_init(ent_scratch_bigfr);
1593
1594         Veuler = make_bigfr(0.0, 2048UL);
1595         bigfr_set_long(ent_scratch_bigfr, 1L);
1596         mpfr_exp(XBIGFR_DATA(Veuler), ent_scratch_bigfr, GMP_RNDN);
1597
1598         Veuler_mascheroni = make_bigfr(0.0, 2048UL);
1599         mpfr_const_euler(XBIGFR_DATA(Veuler_mascheroni), GMP_RNDN);
1600
1601         Vpi = make_bigfr(0.0, 2048UL);
1602         mpfr_const_pi(XBIGFR_DATA(Vpi), GMP_RNDN);
1603 }
1604
1605 void syms_of_ent_mpfr(void)
1606 {
1607         INIT_LRECORD_IMPLEMENTATION(bigfr);
1608
1609         DEFSUBR(Fbigfr_get_precision);
1610         DEFSUBR(Fbigfr_set_precision);
1611
1612         bigfr_set_default_prec(128UL);
1613 }
1614
1615 void vars_of_ent_mpfr(void)
1616 {
1617         /* define pi and e */
1618
1619         /* just some dummy values atm, to make the dumper smile */
1620         Veuler = make_int(1L);
1621         Veuler_mascheroni = make_int(1L);
1622         Vpi = make_int(1L);
1623
1624         DEFVAR_CONST_LISP("euler", &Veuler /*
1625 The value of Euler's constant e (2.7182818...).
1626                                            */);
1627         DEFVAR_CONST_LISP("euler-mascheroni", &Veuler_mascheroni /*
1628 The value of the Euler-Mascheroni constant (0.5772156...).
1629                                                                  */);
1630         DEFVAR_CONST_LISP("pi", &Vpi /*
1631 The value of pi (3.1415926...).
1632                                      */);
1633
1634         Fprovide(intern("bigfr"));
1635 }
1636