Merge branch 'master' of ssh://dio.dreamhost.com/~/repos.nelsonferreira.com/git/sxema...
[sxemacs] / src / ent / ent-gaussian.c
1 /*
2   ent-gaussian.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-float.h"
31 #include "ent-mpfr.h"
32 #include "ent-gaussian.h"
33 #ifdef HAVE_MPC
34 #include "ent-mpc.h"
35 #endif
36
37 bigg ent_scratch_bigg;
38 static ase_nullary_operation_f Qent_gaussian_zero, Qent_gaussian_one;
39
40 \f
41 static void
42 bigg_print(Lisp_Object obj, Lisp_Object printcharfun, int SXE_UNUSED(escapeflag))
43 {
44         Bufbyte *fstr = bigg_to_string(XBIGG_DATA(obj), 10);
45         write_c_string((char*)fstr, printcharfun);
46         xfree(fstr);
47         fstr = (Bufbyte *)NULL;
48         return;
49 }
50
51 static int
52 bigg_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
53 {
54         return bigg_eql(XBIGG_DATA(obj1), XBIGG_DATA(obj2));
55
56         /* less warnings */
57         if (depth);
58 }
59
60 static unsigned long
61 bigg_hash(Lisp_Object obj, int depth)
62 {
63         return bigg_hashcode(XBIGG_DATA(obj));
64
65         /* less warnings */
66         if (depth);
67 }
68
69 static Lisp_Object
70 bigg_mark(Lisp_Object obj)
71 {
72         return Qnil;
73
74         /* less warnings */
75         if (obj == Qnil);
76 }
77
78 static void
79 bigg_finalise(void *header, int for_disksave)
80 {
81         if (for_disksave)
82                 signal_simple_error
83                         ("Can't dump an emacs containing "
84                          "pseudo-gaussian objects",Qt);
85
86         /* less warnings */
87         if (header);
88 }
89
90 static const struct lrecord_description bigg_description[] = {
91         { XD_OPAQUE_DATA_PTR, offsetof(Lisp_Bigg, data) },
92         { XD_END }
93 };
94
95 DEFINE_BASIC_LRECORD_IMPLEMENTATION("bigg", bigg,
96                                     bigg_mark, bigg_print, bigg_finalise,
97                                     bigg_equal, bigg_hash,
98                                     bigg_description, Lisp_Bigg);
99
100 DEFUN("make-bigg", Fmake_bigg, 2, 2, 0, /*
101 Return the Gaussian number whose rational component is REAL-PART
102 and whose imaginary component is IMAGINARY-PART.
103 */
104        (real_part, imaginary_part))
105 {
106         CHECK_COMPARABLE(real_part);
107         CHECK_COMPARABLE(imaginary_part);
108
109         {
110                 Lisp_Object tmp_r = Fcoerce_number(real_part, Qbigz, Qnil);
111                 Lisp_Object tmp_i = Fcoerce_number(imaginary_part, Qbigz, Qnil);
112                 return make_bigg_bz(XBIGZ_DATA(tmp_r), XBIGZ_DATA(tmp_i));
113         }
114 }
115
116 \f
117 /* basic functions */
118 void bigg_init(bigg g)
119 {
120         bigz_init(bigg_re(g));
121         bigz_init(bigg_im(g));
122 }
123
124 void bigg_fini(bigg g)
125 {
126         bigz_fini(bigg_re(g));
127         bigz_fini(bigg_im(g));
128 }
129
130 unsigned long bigg_hashcode(bigg g)
131 {
132         return (bigz_hashcode(bigg_re(g)) ^
133                 bigz_hashcode(bigg_im(g)));
134 }
135
136 Bufbyte *bigg_to_string(bigg g, int base)
137 {
138         Bufbyte *intg_str;
139         Bufbyte *imag_str;
140         int intg_len, imag_len;
141         int sign, neg;
142
143         intg_str = (Bufbyte*)bigz_to_string(bigg_re(g), base);
144         imag_str = (Bufbyte*)bigz_to_string(bigg_im(g), base);
145
146         intg_len = strlen((char*)intg_str);
147         imag_len = strlen((char*)imag_str);
148
149         sign = bigz_sign(bigg_im(g));
150         neg = (sign >= 0) ? 1 : 0;
151
152         /* now append the imaginary string */
153         XREALLOC_ARRAY(intg_str, Bufbyte, intg_len + neg + imag_len + 2);
154         if (neg)
155                 intg_str[intg_len] = '+';
156         memmove(&intg_str[intg_len + neg],
157                 &imag_str[0],
158                 imag_len);
159         intg_str[intg_len+neg+imag_len] = 'i';
160         intg_str[intg_len+neg+imag_len+1] = '\0';
161         xfree(imag_str);
162
163         return intg_str;
164 }
165
166 /***** Bigg: converting assignments *****/
167 void bigg_set(bigg g1,bigg g2)
168 {
169         bigz_set(bigg_re(g1), bigg_re(g2));
170         bigz_set(bigg_im(g1), bigg_im(g2));
171 }
172
173 void bigg_set_long(bigg g, long l)
174 {
175         bigz_set_long(bigg_re(g), l);
176         bigz_set_long(bigg_im(g), 0L);
177 }
178
179 void bigg_set_long_long(bigg g, long l1, long l2)
180 {
181         bigz_set_long(bigg_re(g), l1);
182         bigz_set_long(bigg_im(g), l2);
183 }
184
185 void bigg_set_ulong(bigg g, unsigned long ul)
186 {
187         bigz_set_ulong(bigg_re(g), ul);
188         bigz_set_ulong(bigg_im(g), 0UL);
189 }
190
191 void bigg_set_ulong_ulong(bigg g, unsigned long ul1, unsigned long ul2)
192 {
193         bigz_set_ulong(bigg_re(g), ul1);
194         bigz_set_ulong(bigg_im(g), ul2);
195 }
196
197 void bigg_set_bigz(bigg g, bigz z)
198 {
199         bigz_set(bigg_re(g), z);
200         bigz_set_long(bigg_im(g), 0L);
201 }
202
203 void bigg_set_bigz_bigz(bigg g, bigz z1, bigz z2)
204 {
205         bigz_set(bigg_re(g), z1);
206         bigz_set(bigg_im(g), z2);
207 }
208
209 /* void bigc_set_bigg(bigc c, bigg g)
210  * {
211  *      bigc_set_bigfr_bigfr(bigg_re(g), z1);
212  * }
213  */
214
215 /***** Bigg: comparisons *****/
216 int bigg_eql(bigg g1, bigg g2)
217 {
218         return ((bigz_eql(bigg_re(g1), bigg_re(g2))) &&
219                 (bigz_eql(bigg_im(g1), bigg_im(g2))));
220 }
221
222 /***** Bigg: arithmetic *****/
223 #if defined HAVE_MPFR && defined WITH_MPFR
224 void bigg_abs(bigfr res, bigg g)
225 {
226         /* the absolute archimedean valuation of a+bi is defined as:
227          * (a^2 + b^2)^(1/2)
228          */
229         bigz accu1, accu2, bz;
230         bigz_init(accu1);
231         bigz_init(accu2);
232         bigz_init(bz);
233
234         bigz_mul(accu1, bigg_re(g), bigg_re(g));
235         bigz_mul(accu2, bigg_im(g), bigg_im(g));
236         bigz_add(bz, accu1, accu2);
237
238         bigfr_set_bigz(res, bz);
239         bigfr_sqrt(res, res);
240
241         bigz_fini(accu1);
242         bigz_fini(accu2);
243         bigz_fini(bz);
244 }
245 #endif
246
247 void bigg_norm(bigz res, bigg g)
248 {
249         /* norm is the square of the absolute archimedean valuation */
250         bigz accu1, accu2;
251         bigz_init(accu1);
252         bigz_init(accu2);
253
254         bigz_mul(accu1, bigg_re(g), bigg_re(g));
255         bigz_mul(accu2, bigg_im(g), bigg_im(g));
256         bigz_add(res, accu1, accu2);
257
258         bigz_fini(accu1);
259         bigz_fini(accu2);
260 }
261
262 void bigg_neg(bigg res, bigg g)
263 {
264         /* negation is defined point-wise */
265         bigz_neg(bigg_re(res), bigg_re(g));
266         bigz_neg(bigg_im(res), bigg_im(g));
267 }
268
269 void bigg_conj(bigg res, bigg g)
270 {
271         bigg_set(res, g);
272         bigz_neg(bigg_im(res), bigg_im(res));
273 }
274
275 void bigg_add(bigg res, bigg g1, bigg g2)
276 {
277         /* addition is defined point-wise */
278         bigz accu1, accu2;
279         bigz_init(accu1);
280         bigz_init(accu2);
281
282         bigz_add(accu1, bigg_re(g1), bigg_re(g2));
283         bigz_add(accu2, bigg_im(g1), bigg_im(g2));
284         bigg_set_bigz_bigz(res, accu1, accu2);
285
286         bigz_fini(accu1);
287         bigz_fini(accu2);
288 }
289
290 void bigg_sub(bigg res, bigg g1, bigg g2)
291 {
292         /* subtraction is defined point-wise */
293         bigz_sub(bigg_re(res), bigg_re(g1), bigg_re(g2));
294         bigz_sub(bigg_im(res), bigg_im(g1), bigg_im(g2));
295 }
296
297 void bigg_mul(bigg res, bigg g1, bigg g2)
298 {
299         /* multiplication is defined as:
300          * (a + bi)*(c + di) = (ac - bd) + (ad + bc)i
301          */
302         bigz accu1, accu2, accu3, accu4;
303         bigz_init(accu1);
304         bigz_init(accu2);
305         bigz_init(accu3);
306         bigz_init(accu4);
307
308         bigz_mul(accu1, bigg_re(g1), bigg_re(g2));
309         bigz_mul(accu2, bigg_im(g1), bigg_im(g2));
310         bigz_mul(accu3, bigg_re(g1), bigg_im(g2));
311         bigz_mul(accu4, bigg_im(g1), bigg_re(g2));
312
313         bigz_sub(bigg_re(res), accu1, accu2);
314         bigz_add(bigg_im(res), accu3, accu4);
315
316         bigz_fini(accu1);
317         bigz_fini(accu2);
318         bigz_fini(accu3);
319         bigz_fini(accu4);
320 }
321
322 void bigg_div(bigg res, bigg g1, bigg g2)
323 {
324         /* division is defined as:
325          * (a + bi) div (c + di) = ((a+bi)*(c-di)) div (c*c+d*d)
326          */
327         bigz accu1, accu2;
328         bigg accug;
329         bigz_init(accu1);
330         bigz_init(accu2);
331         bigg_init(accug);
332
333         /* compute: c^2 + d^2 */
334         bigz_mul(accu1, bigg_re(g2), bigg_re(g2));
335         bigz_mul(accu2, bigg_im(g2), bigg_im(g2));
336         bigz_add(accu1, accu1, accu2);
337
338         /* do normal multiplication with conjugate of g2 */
339         bigg_conj(accug, g2);
340         bigg_mul(accug, g1, accug);
341
342         bigg_set(res, accug);
343
344         /* now divide (g1*conj(g2)) by c^2+d^2 (point-wise) */
345         bigz_div(bigg_re(res), bigg_re(accug), accu1);
346         bigz_div(bigg_im(res), bigg_im(accug), accu1);
347
348         bigg_fini(accug);
349         bigz_fini(accu2);
350         bigz_fini(accu1);
351 }
352
353 void bigg_mod(bigg res, bigg g1, bigg g2)
354 {
355         /* the modulo relation is defined as:
356          * (a + bi) mod (c + di) ~
357          * (a+bi) - ((a+bi) div (c-di)) * (c+di)
358          */
359         bigg accug;
360         bigg_init(accug);
361
362         /* do normal division */
363         bigg_div(accug, g1, g2);
364
365         /* now re-multiply g2 */
366         bigg_mul(accug, accug, g2);
367
368         /* and find the difference */
369         bigg_sub(res, g1, accug);
370
371         bigg_fini(accug);
372 }
373
374 void bigg_pow(bigg res, bigg g1, unsigned long g2)
375 {
376 #if defined(HAVE_MPZ) && defined(WITH_GMP)
377         unsigned long i;
378         bigz bin, resintg, resimag, tmpbz1, tmpbz2, tmpbz3, intg, imag;
379
380         bigz_init(bin);
381         bigz_init(resintg);
382         bigz_init(resimag);
383         bigz_init(intg);
384         bigz_init(imag);
385         bigz_init(tmpbz1);
386         bigz_init(tmpbz2);
387         bigz_init(tmpbz3);
388
389         bigz_set_long(resintg, 0L);
390         bigz_set_long(resimag, 0L);
391
392         bigz_set(intg, bigg_re(g1));
393         bigz_set(imag, bigg_im(g1));
394
395         /* we compute using the binomial coefficients */
396         for (i=0; i<=g2; i++) {
397                 mpz_bin_uiui(bin, g2, i);
398                 if (i % 2 == 0) {
399                         /* real part changes */
400                         bigz_pow(tmpbz1, intg, g2-i);
401                         bigz_pow(tmpbz2, imag, i);
402                         bigz_mul(tmpbz3, tmpbz1, tmpbz2);
403                         bigz_mul(bin, bin, tmpbz3);
404                         if (i % 4 == 0) {
405                                 bigz_add(resintg, resintg, bin);
406                         } else if (i % 4 == 2) {
407                                 bigz_sub(resintg, resintg, bin);
408                         }
409                 } else {
410                         /* imag part changes */
411                         bigz_pow(tmpbz1, intg, g2-i);
412                         bigz_pow(tmpbz2, imag, i);
413                         bigz_mul(tmpbz3, tmpbz1, tmpbz2);
414                         bigz_mul(bin, bin, tmpbz3);
415                         if (i % 4 == 1) {
416                                 bigz_add(resimag, resimag, bin);
417                         } else if (i % 4 == 3) {
418                                 bigz_sub(resimag, resimag, bin);
419                         }
420                 }
421         }
422
423         bigg_set_bigz_bigz(res, resintg, resimag);
424
425         bigz_fini(bin);
426         bigz_fini(intg);
427         bigz_fini(imag);
428         bigz_init(resintg);
429         bigz_init(resimag);
430         bigz_fini(tmpbz1);
431         bigz_fini(tmpbz2);
432         bigz_fini(tmpbz3);
433 #else
434         bigg_set_long_long(res, 0L, 0L);
435 #endif
436 }
437
438 Lisp_Object read_bigg_string(char *cp)
439 {
440         bigz bz_re, bz_im;
441         int sign;
442         Lisp_Object result;
443         Bufbyte *end;
444         Bufbyte tmp;
445
446         bigz_init(bz_re);
447         bigz_init(bz_im);
448
449         /* MPZ bigz_set_string has no effect
450          * with initial + sign */
451         if (*cp == '+')
452                 cp++;
453
454         end = (Bufbyte *)cp;
455
456         if (*cp == '-') {
457                 /* jump over a leading minus */
458                 cp++;
459         }
460
461         while ((*cp >= '0' && *cp <= '9'))
462                 cp++;
463
464         /* MPZ cannot read numbers with characters after them.
465          * See limitations below in convert GMP-MPZ strings
466          */
467         tmp = (Bufbyte)*cp;
468         *cp = '\0';
469         bigz_set_string(bz_re, (char *)end, 0);
470         *cp = tmp;
471
472         /* read the imaginary part */
473         sign = 0;
474         if (*cp == '+') {
475                 cp++;
476                 sign = 1;
477         }
478         if (*cp == '-') {
479                 cp++;
480                 sign = -1;
481         }
482         if ((*cp == 'i' || *cp == 'I') && (sign == 1)) {
483                 /* expand +i to +1i and -i to -1i */
484                 bigz_set_long(bz_im, 1L);
485         } else if ((*cp == 'i' || *cp == 'I') && (sign == -1)) {
486                 /* expand +i to +1i and -i to -1i */
487                 bigz_set_long(bz_im, -1L);
488         } else if (sign == 0) {
489                 /* obviously we did not have a+bi,
490                  * but merely bi
491                  */
492                 bigz_set(bz_im, bz_re);
493                 bigz_set_long(bz_re, 0L);
494         } else {
495                 end = (Bufbyte*)cp;
496                 if (sign == -1)
497                         end--;
498                 while ((*cp >= '0' && *cp <= '9'))
499                         cp++;
500                 tmp = (Bufbyte)*cp;
501                 *cp = '\0';
502                 bigz_set_string(bz_im, (char *)end, 0);
503                 *cp = tmp;
504         }
505
506         result = make_bigg_bz(bz_re, bz_im);
507
508         bigz_fini(bz_re);
509         bigz_fini(bz_im);
510         return result;
511 }
512
513 /* bigg ops */
514 static inline int
515 ent_gaussian_zerop(Lisp_Object o)
516 {
517         return (bigz_sign(bigg_re(XBIGG_DATA(o))) == 0 &&
518                 bigz_sign(bigg_im(XBIGG_DATA(o))) == 0);
519 }
520
521 static inline int
522 ent_gaussian_onep(Lisp_Object o)
523 {
524         return ((bigz_fits_long_p(bigg_re(XBIGG_DATA(o))) &&
525                  bigz_to_long(bigg_re(XBIGG_DATA(o))) == 1L) &&
526                 bigz_sign(bigg_im(XBIGG_DATA(o))) == 0);
527 }
528
529 static inline int
530 ent_gaussian_unitp(Lisp_Object o)
531 {
532         return (!ent_gaussian_zerop(o) &&
533                 (bigz_fits_long_p(bigg_re(XBIGG_DATA(o))) &&
534                  (bigz_to_long(bigg_re(XBIGG_DATA(o))) == 0L ||
535                   bigz_to_long(bigg_re(XBIGG_DATA(o))) == 1L ||
536                   bigz_to_long(bigg_re(XBIGG_DATA(o))) == -1L)) &&
537                 (bigz_fits_long_p(bigg_im(XBIGG_DATA(o))) &&
538                  (bigz_to_long(bigg_im(XBIGG_DATA(o))) == 0L ||
539                   bigz_to_long(bigg_im(XBIGG_DATA(o))) == 1L ||
540                   bigz_to_long(bigg_im(XBIGG_DATA(o))) == -1L)));
541 }
542
543 static inline Lisp_Object
544 ent_sum_BIGG_T(Lisp_Object l, Lisp_Object r)
545 {
546         bigg_add(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
547         return make_bigg_bg(ent_scratch_bigg);
548 }
549 static inline Lisp_Object
550 ent_sum_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
551 {
552         CHECK_COMPARABLE(r);
553
554         r = ent_lift(r, BIGZ_T, NULL);
555
556         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(r));
557         bigg_add(ent_scratch_bigg, XBIGG_DATA(l), ent_scratch_bigg);
558         return make_bigg_bg(ent_scratch_bigg);
559 }
560 static inline Lisp_Object
561 ent_sum_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
562 {
563         CHECK_COMPARABLE(l);
564
565         l = ent_lift(l, BIGZ_T, NULL);
566
567         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(l));
568         bigg_add(ent_scratch_bigg, ent_scratch_bigg, XBIGG_DATA(r));
569         return make_bigg_bg(ent_scratch_bigg);
570 }
571
572 static inline Lisp_Object
573 ent_diff_BIGG_T(Lisp_Object l, Lisp_Object r)
574 {
575         bigg_sub(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
576         return make_bigg_bg(ent_scratch_bigg);
577 }
578 static inline Lisp_Object
579 ent_diff_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
580 {
581         CHECK_COMPARABLE(r);
582
583         r = ent_lift(r, BIGZ_T, NULL);
584
585         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(r));
586         bigg_sub(ent_scratch_bigg, XBIGG_DATA(l), ent_scratch_bigg);
587         return make_bigg_bg(ent_scratch_bigg);
588 }
589 static inline Lisp_Object
590 ent_diff_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
591 {
592         CHECK_COMPARABLE(l);
593
594         l = ent_lift(l, BIGZ_T, NULL);
595
596         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(l));
597         bigg_sub(ent_scratch_bigg, ent_scratch_bigg, XBIGG_DATA(r));
598         return make_bigg_bg(ent_scratch_bigg);
599 }
600
601 static inline Lisp_Object
602 ent_neg_BIGG_T(Lisp_Object l)
603 {
604         bigg_neg(ent_scratch_bigg, XBIGG_DATA(l));
605         return make_bigg_bg(ent_scratch_bigg);
606 }
607
608 static inline Lisp_Object
609 ent_prod_BIGG_T(Lisp_Object l, Lisp_Object r)
610 {
611         bigg_mul(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
612         return make_bigg_bg(ent_scratch_bigg);
613 }
614 static inline Lisp_Object
615 ent_prod_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
616 {
617         CHECK_COMPARABLE(r);
618
619         r = ent_lift(r, BIGZ_T, NULL);
620
621         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(r));
622         bigg_mul(ent_scratch_bigg, XBIGG_DATA(l), ent_scratch_bigg);
623         return make_bigg_bg(ent_scratch_bigg);
624 }
625 static inline Lisp_Object
626 ent_prod_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
627 {
628         CHECK_COMPARABLE(l);
629
630         l = ent_lift(l, BIGZ_T, NULL);
631
632         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(l));
633         bigg_mul(ent_scratch_bigg, ent_scratch_bigg, XBIGG_DATA(r));
634         return make_bigg_bg(ent_scratch_bigg);
635 }
636
637 static inline Lisp_Object
638 ent_div_BIGG_T(Lisp_Object l, Lisp_Object r)
639 {
640         if (ent_gaussian_zerop(r)) {
641                 if (!ent_gaussian_zerop(l)) {
642                         return make_indef(COMPLEX_INFINITY);
643                 } else {
644                         return make_indef(NOT_A_NUMBER);
645                 }
646         }
647         bigg_div(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
648         return make_bigg_bg(ent_scratch_bigg);
649 }
650 static inline Lisp_Object
651 ent_div_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
652 {
653         CHECK_COMPARABLE(r);
654
655         if (ent_unrel_zerop(l)) {
656                 if (!ent_gaussian_zerop(l)) {
657                         return make_indef(COMPLEX_INFINITY);
658                 } else {
659                         return make_indef(NOT_A_NUMBER);
660                 }
661         }
662
663         r = ent_lift(r, BIGZ_T, NULL);
664
665         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(r));
666         bigg_div(ent_scratch_bigg, XBIGG_DATA(l), ent_scratch_bigg);
667         return make_bigg_bg(ent_scratch_bigg);
668 }
669 static inline Lisp_Object
670 ent_div_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
671 {
672         CHECK_COMPARABLE(l);
673
674         if (ent_gaussian_zerop(r)) {
675                 if (!ent_unrel_zerop(l)) {
676                         return make_indef(COMPLEX_INFINITY);
677                 } else {
678                         return make_indef(NOT_A_NUMBER);
679                 }
680         }
681
682         l = ent_lift(l, BIGZ_T, NULL);
683
684         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(l));
685         bigg_div(ent_scratch_bigg, ent_scratch_bigg, XBIGG_DATA(r));
686         return make_bigg_bg(ent_scratch_bigg);
687 }
688
689 #if defined HAVE_MPC && defined WITH_MPC ||     \
690         defined HAVE_PSEUC && defined WITH_PSEUC
691 static inline Lisp_Object
692 ent_quo_BIGG_T(Lisp_Object l, Lisp_Object r)
693 {
694         Lisp_Object tmp_l, tmp_r;
695
696         if (ent_gaussian_zerop(r)) {
697                 if (!ent_gaussian_zerop(l)) {
698                         return make_indef(COMPLEX_INFINITY);
699                 } else {
700                         return make_indef(NOT_A_NUMBER);
701                 }
702         }
703
704         bigc_set_prec(ent_scratch_bigc, internal_get_precision(Qnil));
705         tmp_l = Fcoerce_number(l, Qbigc, Qnil);
706         tmp_r = Fcoerce_number(r, Qbigc, Qnil);
707         bigc_div(ent_scratch_bigc, XBIGC_DATA(tmp_l), XBIGC_DATA(tmp_r));
708         return make_bigc_bc(ent_scratch_bigc);
709 }
710 static inline Lisp_Object
711 ent_quo_BIGG_T_COMPARABLE(Lisp_Object l, Lisp_Object r)
712 {
713         CHECK_COMPARABLE(r);
714
715         if (ent_unrel_zerop(r)) {
716                 if (!ent_gaussian_zerop(l)) {
717                         return make_indef(COMPLEX_INFINITY);
718                 } else {
719                         return make_indef(NOT_A_NUMBER);
720                 }
721         }
722
723         l = ent_lift(l, BIGC_T, NULL);
724         return ent_binop(ASE_BINARY_OP_QUO, l, r);
725 }
726 static inline Lisp_Object
727 ent_quo_COMPARABLE_BIGG_T(Lisp_Object l, Lisp_Object r)
728 {
729         CHECK_COMPARABLE(l);
730
731         if (ent_gaussian_zerop(r)) {
732                 if (!ent_unrel_zerop(l)) {
733                         return make_indef(COMPLEX_INFINITY);
734                 } else {
735                         return make_indef(NOT_A_NUMBER);
736                 }
737         }
738
739         r = ent_lift(r, BIGC_T, NULL);
740         return ent_binop(ASE_BINARY_OP_QUO, l, r);
741 }
742 #endif
743
744 static inline Lisp_Object
745 ent_inv_BIGG_T(Lisp_Object r)
746 {
747         if (ent_gaussian_zerop(r)) {
748                 return make_indef(COMPLEX_INFINITY);
749         }
750         bigg_div(ent_scratch_bigg,
751                  XBIGG_DATA(Qent_gaussian_one), XBIGG_DATA(r));
752         return make_bigg_bg(ent_scratch_bigg);
753 }
754 static inline Lisp_Object
755 ent_rem_BIGG_T(Lisp_Object l, Lisp_Object r)
756 {
757         if (ent_gaussian_zerop(r)) {
758                 return make_bigg(0, 0);
759         }
760         bigg_mod(ent_scratch_bigg, XBIGG_DATA(l), XBIGG_DATA(r));
761         return make_bigg_bg(ent_scratch_bigg);
762 }
763 static inline Lisp_Object
764 ent_pow_BIGG_T_integer(Lisp_Object l, Lisp_Object r)
765 {
766         long unsigned int expo = 0UL;
767
768         if (INTP(r)) {
769                 expo = ent_int(r);
770         } else if (BIGZP(r)) {
771                 if (bigz_fits_ulong_p(XBIGZ_DATA(r)))
772                         expo = bigz_to_ulong(XBIGZ_DATA(r));
773                 else
774                         Fsignal(Qarith_error, r);
775         } else {
776                 Fsignal(Qdomain_error, r);
777         }
778         bigg_pow(ent_scratch_bigg, XBIGG_DATA(l), expo);
779         return make_bigg_bg(ent_scratch_bigg);
780 }
781
782 /* relations */
783 static inline int
784 ent_eq_bigg(Lisp_Object l, Lisp_Object r)
785 {
786         return (bigz_eql(bigg_re(XBIGG_DATA(l)), bigg_re(XBIGG_DATA(r))) &&
787                 bigz_eql(bigg_im(XBIGG_DATA(l)), bigg_im(XBIGG_DATA(r))));
788 }
789
790 static inline int
791 ent_ne_bigg(Lisp_Object l, Lisp_Object r)
792 {
793         return !(bigz_eql(bigg_re(XBIGG_DATA(l)), bigg_re(XBIGG_DATA(r))) &&
794                  bigz_eql(bigg_im(XBIGG_DATA(l)), bigg_im(XBIGG_DATA(r))));
795 }
796
797 #if 0
798 static inline Lisp_Object
799 ent_vallt_BIGG_T(Lisp_Object l, Lisp_Object r)
800 {
801         bigz b2;
802         int result;
803
804         bigz_init(b2);
805         bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
806         bigg_norm(b2, XBIGG_DATA(r));
807         result = bigz_lt(ent_scratch_bigz, b2);
808
809         bigz_fini(b2);
810         return (result) ? Qt : Qnil;
811 }
812 static inline Lisp_Object
813 ent_valgt_BIGG_T(Lisp_Object l, Lisp_Object r)
814 {
815         bigz b2;
816         int result;
817
818         bigz_init(b2);
819         bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
820         bigg_norm(b2, XBIGG_DATA(r));
821         result = bigz_gt(ent_scratch_bigz, b2);
822
823         bigz_fini(b2);
824         return (result) ? Qt : Qnil;
825 }
826 static inline Lisp_Object
827 ent_valeq_BIGG_T(Lisp_Object l, Lisp_Object r)
828 {
829         bigz b2;
830         int result;
831
832         bigz_init(b2);
833         bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
834         bigg_norm(b2, XBIGG_DATA(r));
835         result = bigz_eql(ent_scratch_bigz, b2);
836
837         bigz_fini(b2);
838         return (result) ? Qt : Qnil;
839 }
840 static inline Lisp_Object
841 ent_valne_BIGG_T(Lisp_Object l, Lisp_Object r)
842 {
843         bigz b2;
844         int result;
845
846         bigz_init(b2);
847         bigg_norm(ent_scratch_bigz, XBIGG_DATA(l));
848         bigg_norm(b2, XBIGG_DATA(r));
849         result = bigz_eql(ent_scratch_bigz, b2);
850
851         bigz_fini(b2);
852         return (result) ? Qnil : Qt;
853 }
854 #endif
855
856 \f
857 static Lisp_Object
858 ent_lift_all_BIGG_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
859 {
860         number = ent_lift(number, BIGZ_T, NULL);
861         bigg_set_bigz(ent_scratch_bigg, XBIGZ_DATA(number));
862         return make_bigg_bg(ent_scratch_bigg);
863 }
864
865 #if defined HAVE_MPC && defined WITH_MPC ||     \
866         defined HAVE_PSEUC && defined WITH_PSEUC
867 static Lisp_Object
868 ent_lift_BIGC_T_BIGG_T(Lisp_Object number, ent_lift_args_t SXE_UNUSED(la))
869 {
870         Lisp_Object re, im;
871
872         re = Freal_part(number);
873         re = ent_lift(re, BIGZ_T, NULL);
874         im = Fimaginary_part(number);
875         im = ent_lift(im, BIGZ_T, NULL);
876
877         return make_bigg_bz(XBIGZ_DATA(re), XBIGZ_DATA(im));
878 }
879 #endif
880
881 \f
882 static inline void
883 ent_gaussian_nullary_optable_init(void)
884 {
885         Qent_gaussian_zero = make_bigg(0L, 0L);
886         Qent_gaussian_one = make_bigg(1L, 0L);
887         staticpro(&Qent_gaussian_zero);
888         staticpro(&Qent_gaussian_one);
889
890         ent_nullop_register(ASE_NULLARY_OP_ZERO, BIGG_T, Qent_gaussian_zero);
891         ent_nullop_register(ASE_NULLARY_OP_ONE, BIGG_T, Qent_gaussian_one);
892 }
893
894 static inline void
895 ent_gaussian_unary_optable_init(void)
896 {
897         ent_unop_register(ASE_UNARY_OP_NEG, BIGG_T, ent_neg_BIGG_T);
898         ent_unop_register(ASE_UNARY_OP_INV, BIGG_T, ent_inv_BIGG_T);
899 }
900
901 static inline void
902 ent_gaussian_binary_optable_init(void)
903 {
904         /* sums */
905         ent_binop_register(ASE_BINARY_OP_SUM,
906                            BIGG_T, BIGG_T, ent_sum_BIGG_T);
907         ent_binop_register(ASE_BINARY_OP_SUM,
908                            BIGG_T, INT_T, ent_sum_BIGG_T_COMPARABLE);
909         ent_binop_register(ASE_BINARY_OP_SUM,
910                            INT_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
911 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
912         ent_binop_register(ASE_BINARY_OP_SUM,
913                            BIGG_T, BIGZ_T, ent_sum_BIGG_T_COMPARABLE);
914         ent_binop_register(ASE_BINARY_OP_SUM,
915                            BIGZ_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
916 #endif
917 #if defined HAVE_MPQ && defined WITH_GMP
918         ent_binop_register(ASE_BINARY_OP_SUM,
919                            BIGG_T, BIGQ_T, ent_sum_BIGG_T_COMPARABLE);
920         ent_binop_register(ASE_BINARY_OP_SUM,
921                            BIGQ_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
922 #endif
923 #if defined HAVE_MPF && defined WITH_GMP
924         ent_binop_register(ASE_BINARY_OP_SUM,
925                            BIGG_T, BIGF_T, ent_sum_BIGG_T_COMPARABLE);
926         ent_binop_register(ASE_BINARY_OP_SUM,
927                            BIGF_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
928 #endif
929 #if defined HAVE_MPFR && defined WITH_MPFR
930         ent_binop_register(ASE_BINARY_OP_SUM,
931                            BIGG_T, BIGFR_T, ent_sum_BIGG_T_COMPARABLE);
932         ent_binop_register(ASE_BINARY_OP_SUM,
933                            BIGFR_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
934 #endif
935 #ifdef HAVE_FPFLOAT
936         ent_binop_register(ASE_BINARY_OP_SUM,
937                            BIGG_T, FLOAT_T, ent_sum_BIGG_T_COMPARABLE);
938         ent_binop_register(ASE_BINARY_OP_SUM,
939                            FLOAT_T, BIGG_T, ent_sum_COMPARABLE_BIGG_T);
940 #endif
941         /* diffs */
942         ent_binop_register(ASE_BINARY_OP_DIFF,
943                            BIGG_T, BIGG_T, ent_diff_BIGG_T);
944         ent_binop_register(ASE_BINARY_OP_DIFF,
945                            BIGG_T, INT_T, ent_diff_BIGG_T_COMPARABLE);
946         ent_binop_register(ASE_BINARY_OP_DIFF,
947                            INT_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
948         ent_binop_register(ASE_BINARY_OP_DIFF,
949                            BIGG_T, BIGZ_T, ent_diff_BIGG_T_COMPARABLE);
950         ent_binop_register(ASE_BINARY_OP_DIFF,
951                            BIGZ_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
952 #if defined HAVE_MPQ && defined WITH_GMP
953         ent_binop_register(ASE_BINARY_OP_DIFF,
954                            BIGG_T, BIGQ_T, ent_diff_BIGG_T_COMPARABLE);
955         ent_binop_register(ASE_BINARY_OP_DIFF,
956                            BIGQ_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
957 #endif
958 #if defined HAVE_MPF && defined WITH_GMP
959         ent_binop_register(ASE_BINARY_OP_DIFF,
960                            BIGG_T, BIGF_T, ent_diff_BIGG_T_COMPARABLE);
961         ent_binop_register(ASE_BINARY_OP_DIFF,
962                            BIGF_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
963 #endif
964 #if defined HAVE_MPFR && defined WITH_MPFR
965         ent_binop_register(ASE_BINARY_OP_DIFF,
966                            BIGG_T, BIGFR_T, ent_diff_BIGG_T_COMPARABLE);
967         ent_binop_register(ASE_BINARY_OP_DIFF,
968                            BIGFR_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
969 #endif
970 #ifdef HAVE_FPFLOAT
971         ent_binop_register(ASE_BINARY_OP_DIFF,
972                            BIGG_T, FLOAT_T, ent_diff_BIGG_T_COMPARABLE);
973         ent_binop_register(ASE_BINARY_OP_DIFF,
974                            FLOAT_T, BIGG_T, ent_diff_COMPARABLE_BIGG_T);
975 #endif
976         /* prods */
977         ent_binop_register(ASE_BINARY_OP_PROD,
978                            BIGG_T, BIGG_T, ent_prod_BIGG_T);
979         ent_binop_register(ASE_BINARY_OP_PROD,
980                            BIGG_T, INT_T, ent_prod_BIGG_T_COMPARABLE);
981         ent_binop_register(ASE_BINARY_OP_PROD,
982                            INT_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
983         ent_binop_register(ASE_BINARY_OP_PROD,
984                            BIGG_T, BIGZ_T, ent_prod_BIGG_T_COMPARABLE);
985         ent_binop_register(ASE_BINARY_OP_PROD,
986                            BIGZ_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
987 #if defined HAVE_MPQ && defined WITH_GMP
988         ent_binop_register(ASE_BINARY_OP_PROD,
989                            BIGG_T, BIGQ_T, ent_prod_BIGG_T_COMPARABLE);
990         ent_binop_register(ASE_BINARY_OP_PROD,
991                            BIGQ_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
992 #endif
993 #if defined HAVE_MPF && defined WITH_GMP
994         ent_binop_register(ASE_BINARY_OP_PROD,
995                            BIGG_T, BIGF_T, ent_prod_BIGG_T_COMPARABLE);
996         ent_binop_register(ASE_BINARY_OP_PROD,
997                            BIGF_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
998 #endif
999 #if defined HAVE_MPFR && defined WITH_MPFR
1000         ent_binop_register(ASE_BINARY_OP_PROD,
1001                            BIGG_T, BIGFR_T, ent_prod_BIGG_T_COMPARABLE);
1002         ent_binop_register(ASE_BINARY_OP_PROD,
1003                            BIGFR_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
1004 #endif
1005 #ifdef HAVE_FPFLOAT
1006         ent_binop_register(ASE_BINARY_OP_PROD,
1007                            BIGG_T, FLOAT_T, ent_prod_BIGG_T_COMPARABLE);
1008         ent_binop_register(ASE_BINARY_OP_PROD,
1009                            FLOAT_T, BIGG_T, ent_prod_COMPARABLE_BIGG_T);
1010 #endif
1011
1012         /* divisions and quotients */
1013         ent_binop_register(ASE_BINARY_OP_DIV,
1014                            BIGG_T, BIGG_T, ent_div_BIGG_T);
1015         ent_binop_register(ASE_BINARY_OP_DIV,
1016                            BIGG_T, INT_T, ent_div_BIGG_T_COMPARABLE);
1017         ent_binop_register(ASE_BINARY_OP_DIV,
1018                            INT_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1019         ent_binop_register(ASE_BINARY_OP_DIV,
1020                            BIGG_T, BIGZ_T, ent_div_BIGG_T_COMPARABLE);
1021         ent_binop_register(ASE_BINARY_OP_DIV,
1022                            BIGZ_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1023 #if defined HAVE_MPQ && defined WITH_GMP
1024         ent_binop_register(ASE_BINARY_OP_DIV,
1025                            BIGG_T, BIGQ_T, ent_div_BIGG_T_COMPARABLE);
1026         ent_binop_register(ASE_BINARY_OP_DIV,
1027                            BIGQ_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1028 #endif
1029 #if defined HAVE_MPF && defined WITH_GMP
1030         ent_binop_register(ASE_BINARY_OP_DIV,
1031                            BIGG_T, BIGF_T, ent_div_BIGG_T_COMPARABLE);
1032         ent_binop_register(ASE_BINARY_OP_DIV,
1033                            BIGF_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1034 #endif
1035 #if defined HAVE_MPFR && defined WITH_MPFR
1036         ent_binop_register(ASE_BINARY_OP_DIV,
1037                            BIGG_T, BIGFR_T, ent_div_BIGG_T_COMPARABLE);
1038         ent_binop_register(ASE_BINARY_OP_DIV,
1039                            BIGFR_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1040 #endif
1041 #ifdef HAVE_FPFLOAT
1042         ent_binop_register(ASE_BINARY_OP_DIV,
1043                            BIGG_T, FLOAT_T, ent_div_BIGG_T_COMPARABLE);
1044         ent_binop_register(ASE_BINARY_OP_DIV,
1045                            FLOAT_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1046 #endif
1047
1048 #if defined HAVE_MPC && defined WITH_MPC ||     \
1049         defined HAVE_PSEUC && defined WITH_PSEUC
1050         ent_binop_register(ASE_BINARY_OP_QUO,
1051                            BIGG_T, BIGG_T, ent_quo_BIGG_T);
1052         ent_binop_register(ASE_BINARY_OP_QUO,
1053                            BIGG_T, BIGZ_T, ent_quo_BIGG_T_COMPARABLE);
1054         ent_binop_register(ASE_BINARY_OP_QUO,
1055                            BIGZ_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1056 #if defined HAVE_MPQ && defined WITH_GMP
1057         ent_binop_register(ASE_BINARY_OP_QUO,
1058                            BIGG_T, BIGQ_T, ent_quo_BIGG_T_COMPARABLE);
1059         ent_binop_register(ASE_BINARY_OP_QUO,
1060                            BIGQ_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1061 #endif
1062 #if defined HAVE_MPF && defined WITH_GMP
1063         ent_binop_register(ASE_BINARY_OP_QUO,
1064                            BIGG_T, BIGF_T, ent_quo_BIGG_T_COMPARABLE);
1065         ent_binop_register(ASE_BINARY_OP_QUO,
1066                            BIGF_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1067 #endif
1068 #if defined HAVE_MPFR && defined WITH_MPFR
1069         ent_binop_register(ASE_BINARY_OP_QUO,
1070                            BIGG_T, BIGFR_T, ent_quo_BIGG_T_COMPARABLE);
1071         ent_binop_register(ASE_BINARY_OP_QUO,
1072                            BIGFR_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1073 #endif
1074 #ifdef HAVE_FPFLOAT
1075         ent_binop_register(ASE_BINARY_OP_QUO,
1076                            BIGG_T, FLOAT_T, ent_quo_BIGG_T_COMPARABLE);
1077         ent_binop_register(ASE_BINARY_OP_QUO,
1078                            FLOAT_T, BIGG_T, ent_quo_COMPARABLE_BIGG_T);
1079 #endif
1080 #else  /* !HAVE_MPC */
1081         ent_binop_register(ASE_BINARY_OP_QUO,
1082                            BIGG_T, BIGG_T, ent_div_BIGG_T);
1083         ent_binop_register(ASE_BINARY_OP_QUO,
1084                            BIGG_T, BIGZ_T, ent_div_BIGG_T_COMPARABLE);
1085         ent_binop_register(ASE_BINARY_OP_QUO,
1086                            BIGZ_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1087 #if defined HAVE_MPQ && defined WITH_GMP
1088         ent_binop_register(ASE_BINARY_OP_QUO,
1089                            BIGG_T, BIGQ_T, ent_div_BIGG_T_COMPARABLE);
1090         ent_binop_register(ASE_BINARY_OP_QUO,
1091                            BIGQ_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1092 #endif
1093 #if defined HAVE_MPF && defined WITH_GMP
1094         ent_binop_register(ASE_BINARY_OP_QUO,
1095                            BIGG_T, BIGF_T, ent_div_BIGG_T_COMPARABLE);
1096         ent_binop_register(ASE_BINARY_OP_QUO,
1097                            BIGF_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1098 #endif
1099 #if defined HAVE_MPFR && defined WITH_MPFR
1100         ent_binop_register(ASE_BINARY_OP_QUO,
1101                            BIGG_T, BIGFR_T, ent_div_BIGG_T_COMPARABLE);
1102         ent_binop_register(ASE_BINARY_OP_QUO,
1103                            BIGFR_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1104 #endif
1105 #ifdef HAVE_FPFLOAT
1106         ent_binop_register(ASE_BINARY_OP_QUO,
1107                            BIGG_T, FLOAT_T, ent_div_BIGG_T_COMPARABLE);
1108         ent_binop_register(ASE_BINARY_OP_QUO,
1109                            FLOAT_T, BIGG_T, ent_div_COMPARABLE_BIGG_T);
1110 #endif
1111 #endif
1112         ent_binop_register(ASE_BINARY_OP_REM,
1113                            BIGG_T, BIGG_T, ent_rem_BIGG_T);
1114         ent_binop_register(ASE_BINARY_OP_MOD,
1115                            BIGG_T, BIGG_T, ent_rem_BIGG_T);
1116         ent_binop_register(ASE_BINARY_OP_POW,
1117                            BIGG_T, INT_T, ent_pow_BIGG_T_integer);
1118         ent_binop_register(ASE_BINARY_OP_POW,
1119                            BIGG_T, BIGZ_T, ent_pow_BIGG_T_integer);
1120 }
1121
1122 static inline void
1123 ent_gaussian_unary_reltable_init(void)
1124 {
1125         ent_unrel_register(ASE_UNARY_REL_ZEROP, BIGG_T, ent_gaussian_zerop);
1126         ent_unrel_register(ASE_UNARY_REL_ONEP, BIGG_T, ent_gaussian_onep);
1127         ent_unrel_register(ASE_UNARY_REL_UNITP, BIGG_T, ent_gaussian_unitp);
1128 }
1129
1130 static inline void
1131 ent_gaussian_binary_reltable_init(void)
1132 {
1133         ent_binrel_register(ASE_BINARY_REL_EQUALP,
1134                             BIGG_T, BIGG_T, ent_eq_bigg);
1135         ent_binrel_register(ASE_BINARY_REL_NEQP,
1136                             BIGG_T, BIGG_T, ent_ne_bigg);
1137 }
1138
1139 static inline void
1140 ent_gaussian_lifttable_init(void)
1141 {
1142         ent_lift_register(INT_T, BIGG_T, ent_lift_all_BIGG_T);
1143         ent_lift_register(BIGZ_T, BIGC_T, ent_lift_all_BIGG_T);
1144 #if defined HAVE_MPQ && defined WITH_GMP
1145         ent_lift_register(BIGQ_T, BIGG_T, ent_lift_all_BIGG_T);
1146 #endif
1147 #if defined HAVE_MPF && defined WITH_GMP
1148         ent_lift_register(BIGF_T, BIGG_T, ent_lift_all_BIGG_T);
1149 #endif
1150 #if defined HAVE_MPFR && defined WITH_MPFR
1151         ent_lift_register(BIGFR_T, BIGG_T, ent_lift_all_BIGG_T);
1152 #endif
1153 #ifdef HAVE_FPFLOAT
1154         ent_lift_register(FLOAT_T, BIGG_T, ent_lift_all_BIGG_T);
1155 #endif
1156 #if defined HAVE_MPC && defined WITH_MPC ||     \
1157         defined HAVE_PSEUC && defined WITH_PSEUC
1158         ent_lift_register(BIGC_T, BIGG_T, ent_lift_BIGC_T_BIGG_T);
1159 #endif
1160 }
1161
1162 void init_optables_BIGG_T(void)
1163 {
1164         ent_gaussian_nullary_optable_init();
1165         ent_gaussian_unary_optable_init();
1166         ent_gaussian_binary_optable_init();
1167         ent_gaussian_unary_reltable_init();
1168         ent_gaussian_binary_reltable_init();
1169         ent_gaussian_lifttable_init();
1170 }
1171
1172 void init_ent_gaussian(void)
1173 {
1174         bigg_init(ent_scratch_bigg);
1175 }
1176
1177 void syms_of_ent_gaussian(void)
1178 {
1179         INIT_LRECORD_IMPLEMENTATION(bigg);
1180
1181         DEFSUBR(Fmake_bigg);
1182 }
1183
1184 void vars_of_ent_gaussian(void)
1185 {
1186         Fprovide(intern("bigg"));
1187         Fprovide(intern("gaussian"));
1188 }