summaryrefslogtreecommitdiff
path: root/src/numb.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/numb.h')
-rw-r--r--src/numb.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/numb.h b/src/numb.h
new file mode 100644
index 00000000..2fa02a58
--- /dev/null
+++ b/src/numb.h
@@ -0,0 +1,156 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "m4.h"
+
+#ifdef WITH_GMP
+#define NUMB_MP 1
+#endif
+
+#ifdef WITH_GMP
+#include "gmp.h"
+
+/* eval_t should be at least 32 bits. */
+typedef mpq_t eval_t;
+
+extern eval_t numb_ZERO;
+extern eval_t numb_ONE;
+
+#define numb_set(ans,i) mpq_set(ans,i)
+#define numb_set_si(ans,i) mpq_set_si(*(ans),(long)i,(unsigned long)1)
+
+#define numb_init(x) mpq_init((x))
+#define numb_fini(x) mpq_clear((x))
+
+#define numb_zerop(x) (mpq_cmp(x,numb_ZERO) == 0)
+#define numb_positivep(x) (mpq_cmp(x,numb_ZERO) > 0)
+#define numb_negativep(x) (mpq_cmp(x,numb_ZERO) < 0)
+
+#define numb_eq(x,y) numb_set(x,mpq_cmp(x,y)==0? numb_ONE: numb_ZERO)
+#define numb_ne(x,y) numb_set(x,mpq_cmp(x,y)!=0? numb_ONE: numb_ZERO)
+#define numb_lt(x,y) numb_set(x,mpq_cmp(x,y)< 0? numb_ONE: numb_ZERO)
+#define numb_le(x,y) numb_set(x,mpq_cmp(x,y)<=0? numb_ONE: numb_ZERO)
+#define numb_gt(x,y) numb_set(x,mpq_cmp(x,y)> 0? numb_ONE: numb_ZERO)
+#define numb_ge(x,y) numb_set(x,mpq_cmp(x,y)>=0? numb_ONE: numb_ZERO)
+
+#define numb_lnot(x) numb_set(x,numb_zerop(x)? numb_ONE: numb_ZERO)
+#define numb_lior(x,y) numb_set(x,numb_zerop(x)? y: numb_ONE)
+#define numb_land(x,y) numb_set(x,numb_zerop(x)? numb_ZERO: y)
+
+#define reduce1(f1,x) \
+{ eval_t T; mpq_init(T); f1(T,x); mpq_set(x,T); mpq_clear(T); }
+#define reduce2(f2,x,y) \
+{ eval_t T; mpq_init(T); f2(T,(x),(y)); mpq_set((x),T); mpq_clear(T); }
+
+#define numb_plus(x,y) reduce2(mpq_add,x,y)
+#define numb_minus(x,y) reduce2(mpq_sub,x,y)
+#define numb_negate(x) reduce1(mpq_neg,x)
+
+#define numb_times(x,y) reduce2(mpq_mul,x,y)
+#define numb_ratio(x,y) reduce2(mpq_div,x,y)
+#define numb_invert(x) reduce1(mpq_inv,x)
+
+#define numb_decr(n) numb_minus(n,numb_ONE)
+
+
+
+void numb_divide(eval_t *x, const eval_t *y);
+void numb_modulo(eval_t *x, const eval_t *y);
+void numb_and(eval_t *x, const eval_t *y);
+void numb_ior(eval_t *x, const eval_t *y);
+void numb_eor(eval_t *x, const eval_t *y);
+void numb_not(eval_t *x);;
+void numb_lshift(eval_t *x, const eval_t *y);
+void numb_rshift(eval_t *x, const eval_t *y);
+void numb_pow (eval_t *x, const eval_t *y);
+
+
+
+
+#else /* not WITH_GMP */
+
+/* eval_t should be at least 32 bits. */
+/* use GNU long long int if available */
+#if defined(SIZEOF_LONG_LONG_INT) && SIZEOF_LONG_LONG_INT > 0
+typedef long long int eval_t;
+typedef unsigned long long int ueval_t;
+#else
+typedef long int eval_t;
+typedef unsigned long int ueval_t;
+#endif
+
+extern eval_t numb_ZERO;
+extern eval_t numb_ONE;
+
+#define int2numb(i) ((eval_t)(i))
+#define numb2int(n) ((n))
+
+#define numb_set(ans,x) ((ans) = x)
+#define numb_set_si(ans,si) (*(ans) = int2numb(si))
+
+#define numb_init(x) x=((eval_t)0)
+#define numb_fini(x)
+
+#define numb_decr(n) (n) -= 1
+
+#define numb_ZERO ((eval_t)0)
+#define numb_ONE ((eval_t)1)
+
+#define numb_zerop(x) ((x) == numb_ZERO)
+#define numb_positivep(x) ((x) > numb_ZERO)
+#define numb_negativep(x) ((x) < numb_ZERO)
+
+
+#define numb_eq(x,y) ((x) = ((x) == (y)))
+#define numb_ne(x,y) ((x) = ((x) != (y)))
+#define numb_lt(x,y) ((x) = ((x) < (y)))
+#define numb_le(x,y) ((x) = ((x) <= (y)))
+#define numb_gt(x,y) ((x) = ((x) > (y)))
+#define numb_ge(x,y) ((x) = ((x) >= (y)))
+
+#define numb_lnot(x) ((x) = (! (x)))
+#define numb_lior(x,y) ((x) = ((x) || (y)))
+#define numb_land(x,y) ((x) = ((x) && (y)))
+
+#define numb_not(x) (*(x) = int2numb(~numb2int(*(x))))
+#define numb_eor(x,y) (*(x) = int2numb(numb2int(*(x)) ^ numb2int(*(y))))
+#define numb_ior(x,y) (*(x) = int2numb(numb2int(*(x)) | numb2int(*(y))))
+#define numb_and(x,y) (*(x) = int2numb(numb2int(*(x)) & numb2int(*(y))))
+
+#define numb_plus(x,y) ((x) = ((x) + (y)))
+#define numb_minus(x,y) ((x) = ((x) - (y)))
+#define numb_negate(x) ((x) = (- (x)))
+
+#define numb_times(x,y) ((x) = ((x) * (y)))
+#define numb_ratio(x,y) ((x) = ((x) / ((y))))
+#define numb_divide(x,y) (*(x) = (*(x) / (*(y))))
+#define numb_modulo(x,y) (*(x) = (*(x) % *(y)))
+#define numb_invert(x) ((x) = 1 / (x))
+
+#define numb_lshift(x,y) (*(x) = (*(x) << *(y)))
+#define numb_rshift(x,y) (*(x) = (*(x) >> *(y)))
+
+void numb_pow (eval_t *x, const eval_t *y);
+
+#endif /* WITH_GMP */
+
+
+void numb_initialise __P((void));
+void numb_obstack __P((struct obstack *obs,
+ const eval_t value,
+ const int radix, int min));