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