source: project/release/4/numbers/trunk/numbers-c.h @ 30582

Last change on this file since 30582 was 30582, checked in by sjamaan, 7 years ago

numbers: Minor simplification by cutting out the ability to turn off assertion checks specifically for bignums. Remove ancient constants BIG_FREE and FORCE_FINALIZERS (which go all the way back to the gmp implementation)

File size: 7.2 KB
Line 
1/* numbers-c.h */
2
3#include <limits.h>
4#include <math.h> /* frexp() */
5
6#define FIX    0
7#define FLO    1
8#define BIG    2
9#define RAT    3
10#define COMP   4
11#define NONE   5
12
13#define BIG_TAG       0
14#define RAT_TAG       1
15#define COMP_TAG      2
16
17enum bignum_bitwise_ops
18{
19  bignum_and_op,
20  bignum_ior_op,
21  bignum_xor_op
22};
23
24enum bignum_comparison
25{
26  bignum_comparison_equal = 0,
27  bignum_comparison_less = -1,
28  bignum_comparison_greater = 1
29};
30
31typedef void * bignum_type;
32typedef C_word bignum_digit_type;
33typedef C_word bignum_length_type;
34
35/* Internal bignum interface */
36static bignum_type bignum_allocate(bignum_length_type, int);
37static bignum_type bignum_allocate_zeroed(bignum_length_type, int);
38static bignum_type shorten_bignum(bignum_type, bignum_length_type);
39static bignum_type bignum_trim(bignum_type);
40static bignum_type bignum_copy(bignum_type);
41static void bignum_destructive_copy(bignum_type, bignum_type);
42static bignum_type bignum_new_sign(bignum_type, int);
43static bignum_type bignum_add(bignum_type, bignum_type);
44static bignum_type bignum_add_unsigned(bignum_type, bignum_type, int);
45static bignum_type bignum_subtract(bignum_type, bignum_type);
46static bignum_type bignum_subtract_unsigned(bignum_type, bignum_type);
47static bignum_type bignum_multiply_unsigned(bignum_type, bignum_type, int);
48static bignum_type bignum_multiply_unsigned_small_factor(bignum_type,
49                                                         bignum_digit_type, int);
50static void bignum_destructive_scale_up(bignum_type, bignum_digit_type);
51static void bignum_destructive_add(bignum_type, bignum_digit_type);
52static void bignum_divide_unsigned_large_denominator(bignum_type, bignum_type,
53                                                     bignum_type *,
54                                                     bignum_type *, int, int);
55static void bignum_divide_unsigned_normalized(bignum_type, bignum_type,
56                                              bignum_type);
57static bignum_digit_type bignum_divide_subtract(bignum_digit_type *,
58                                                bignum_digit_type *,
59                                                bignum_digit_type,
60                                                bignum_digit_type *);
61static void bignum_divide_unsigned_medium_denominator(bignum_type,
62                                                      bignum_digit_type,
63                                                      bignum_type *,
64                                                      bignum_type *,
65                                                      int, int);
66static void bignum_destructive_normalization(bignum_type, bignum_type, int);
67static bignum_type bignum_destructive_unnormalization(bignum_type, int);
68static bignum_digit_type bignum_digit_divide(bignum_digit_type,
69                                             bignum_digit_type,
70                                             bignum_digit_type,
71                                             bignum_digit_type *);
72static bignum_digit_type bignum_digit_divide_subtract(bignum_digit_type,
73                                                      bignum_digit_type,
74                                                      bignum_digit_type,
75                                                      bignum_digit_type *);
76static void bignum_divide_unsigned_small_denominator(bignum_type,
77                                                     bignum_digit_type,
78                                                     bignum_type *,
79                                                     bignum_type *,
80                                                     int, int);
81static bignum_digit_type bignum_destructive_scale_down(bignum_type,
82                                                       bignum_digit_type);
83static bignum_type bignum_remainder_unsigned_small_denominator(bignum_type,
84                                                               bignum_digit_type,
85                                                               int);
86static enum bignum_comparison bignum_compare_unsigned(bignum_type, bignum_type);
87static bignum_type double_to_bignum(double);
88static bignum_type bignum_bitwise_and(bignum_type, bignum_type);
89static bignum_type bignum_bitwise_ior(bignum_type, bignum_type);
90static bignum_type bignum_bitwise_xor(bignum_type, bignum_type);
91static bignum_type bignum_bitwise_not(bignum_type);
92static bignum_type bignum_arithmetic_shift(bignum_type, C_word);
93static bignum_type bignum_magnitude_ash(bignum_type, C_word);
94static bignum_type bignum_pospos_bitwise_op(int, bignum_type, bignum_type);
95static bignum_type bignum_posneg_bitwise_op(int, bignum_type, bignum_type);
96static bignum_type bignum_negneg_bitwise_op(int, bignum_type, bignum_type);
97static void bignum_negate_magnitude(bignum_type);
98
99#define BIGNUM_OUT_OF_BAND NULL
100
101/* BIGNUM_TO_POINTER casts a bignum object to a digit array pointer. */
102#define BIGNUM_TO_POINTER(bignum) ((bignum_digit_type *) (bignum))
103
104/* BIGNUM_REDUCE_LENGTH allows the memory system to reclaim some
105   space when a bignum's length is reduced from its original value. */
106#define BIGNUM_REDUCE_LENGTH(target, source, length)                    \
107     target = shorten_bignum(source, length)
108
109#define BIGNUM_DEALLOCATE(b) (C_free((void *)b))
110
111/* CHAR_BIT is from <limits.h>, and it equals the number of bits in a char */
112#define BIGNUM_DIGIT_LENGTH (((sizeof (bignum_digit_type)) * CHAR_BIT) - 2)
113#define BIGNUM_HALF_DIGIT_LENGTH (BIGNUM_DIGIT_LENGTH / 2)
114/* Radix = highest bit of header word: 1 if number negative, 0 if positive */
115#define BIGNUM_RADIX (((C_uword) 1) << BIGNUM_DIGIT_LENGTH)
116#define BIGNUM_RADIX_ROOT (((C_uword) 1) << BIGNUM_HALF_DIGIT_LENGTH)
117#define BIGNUM_DIGIT_MASK        (BIGNUM_RADIX - 1)
118#define BIGNUM_HALF_DIGIT_MASK   (BIGNUM_RADIX_ROOT - 1)
119
120#define BIGNUM_START_PTR(bignum)                                        \
121  ((BIGNUM_TO_POINTER (bignum)) + 1)
122
123#define BIGNUM_SET_HEADER(bignum, length, negative_p)                   \
124  (* (BIGNUM_TO_POINTER (bignum))) =                                    \
125    ((length) | ((negative_p) ? BIGNUM_RADIX : 0))
126
127#define BIGNUM_LENGTH(bignum)                                           \
128  ((* (BIGNUM_TO_POINTER (bignum))) & ((bignum_length_type) BIGNUM_DIGIT_MASK))
129
130#define BIGNUM_NEGATIVE_P(bignum)                                       \
131  (((* (BIGNUM_TO_POINTER (bignum))) & BIGNUM_RADIX) != 0)
132
133#define BIGNUM_ZERO_P(bignum)                                           \
134  ((BIGNUM_LENGTH (bignum)) == 0)
135
136#define BIGNUM_REF(bignum, index)                                       \
137  (* ((BIGNUM_START_PTR (bignum)) + (index)))
138
139
140/* These definitions are here to facilitate caching of the constants
141   0, 1, and -1. */
142/*
143 * We don't cache because it complicates the conversion to fixnum code
144 * since it would need additional checks before freeing the bignum.
145 * Most cases where BIGNUM_ONE/ZERO are returned are removed anyway.
146 */
147#define BIGNUM_ZERO() (bignum_digit_to_bignum(0, 0))
148#define BIGNUM_ONE(neg_p) (bignum_digit_to_bignum(1, neg_p))
149
150#define HD_LOW(digit) ((digit) & BIGNUM_HALF_DIGIT_MASK)
151#define HD_HIGH(digit) ((digit) >> BIGNUM_HALF_DIGIT_LENGTH)
152#define HD_CONS(high, low) (((high) << BIGNUM_HALF_DIGIT_LENGTH) | (low))
153
154#define BIGNUM_BITS_TO_DIGITS(n)                                        \
155  (((n) + (BIGNUM_DIGIT_LENGTH - 1)) / BIGNUM_DIGIT_LENGTH)
Note: See TracBrowser for help on using the repository browser.