-
Notifications
You must be signed in to change notification settings - Fork 3
/
arith.h
148 lines (119 loc) · 5.12 KB
/
arith.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* Arithmetic for numbers greater than an unsigned long or int, for tar.
Copyright (C) 1996, 1997, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define BITS_PER_BYTE 8 /* number of bits in each sizeof unit */
#define BITS_PER_TARLONG 42 /* wanted number of bits in each tarlong */
/* In all cases, tarlong is the proper type for a big number. tarcell is
either unsigned long, or unsigned int if the former is unavailable.
For straight compiler arithmetic, SUPERDIGIT is zero and TARLONG_FORMAT
is the format to directly print a tarlong (without zero-filling).
For simulated arithmetic, SUPERDIGIT is the base, TARLONG_FORMAT is the
format to print a single super-digit filled with zeroes to the left, and
BITS_PER_SUPERDIGIT is the smallest number of bits required to fully
represent each super-digit. CELLS_PER_TARLONG says how many cells are
required for a full tarlong, and SIZEOF_TARLONG is the size of a tarlong
in bytes.
The values of SIZEOF_UNSIGNED_LONG_LONG, SIZEOF_UNSIGNED_LONG and
SIZEOF_UNSIGNED_INT, below, are obtained through the configuration
process, and SIZEOF_UNSIGNED_LONG_LONG is reset to zero by the
configuration process if printf does not support %llu. If nonzero,
SUPERDIGIT is the biggest power of 10 which fits in half the bits of an
tarcell. See comments at beginning of `arith.c' for more explanations. */
#if BITS_PER_BYTE * SIZEOF_UNSIGNED_INT >= BITS_PER_TARLONG
# define SUPERDIGIT 0
# define TARLONG_FORMAT "%u"
typedef unsigned int tarlong;
#else
# if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= BITS_PER_TARLONG
# define SUPERDIGIT 0
# define TARLONG_FORMAT "%lu"
typedef unsigned long tarlong;
# else
# if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG_LONG >= BITS_PER_TARLONG + 1
# define SUPERDIGIT 0
# define TARLONG_FORMAT "%llu"
typedef unsigned long long tarlong;
# else
# if SIZEOF_UNSIGNED_LONG
typedef unsigned long tarcell;
# if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= 64
# define SUPERDIGIT 1000000000L
# define BITS_PER_SUPERDIGIT 29
# define TARLONG_FORMAT "%09lu"
# else
# if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= 32
# define SUPERDIGIT 10000L
# define BITS_PER_SUPERDIGIT 14
# define TARLONG_FORMAT "%04lu"
# endif
# endif
# else
typedef unsigned int tarcell;
# if BITS_PER_BYTE * SIZEOF_UNSIGNED_INT >= 64
# define SUPERDIGIT 1000000000
# define BITS_PER_SUPERDIGIT 29
# define TARLONG_FORMAT "%09u"
# else
# if BITS_PER_BYTE * SIZEOF_UNSIGNED_INT >= 32
# define SUPERDIGIT 10000
# define BITS_PER_SUPERDIGIT 14
# define TARLONG_FORMAT "%04u"
# endif
# endif
# endif
# endif
# endif
#endif
#if SUPERDIGIT
# define CELLS_PER_TARLONG \
((BITS_PER_TARLONG + BITS_PER_SUPERDIGIT - 1) / BITS_PER_SUPERDIGIT)
# define SIZEOF_TARLONG (CELLS_PER_TARLONG * sizeof (tarcell))
/* The NEC EWS 4.2 C compiler gets confused by a pointer to a typedef that
is an array. So we wrap the array into a struct. (Pouah!) */
struct tarlong
{
tarcell digit[CELLS_PER_TARLONG];
};
typedef struct tarlong tarlong;
bool zerop_tarlong_helper PARAMS ((tarcell *));
bool lessp_tarlong_helper PARAMS ((tarcell *, tarcell *));
void clear_tarlong_helper PARAMS ((tarcell *));
void add_to_tarlong_helper PARAMS ((tarcell *, tarcell));
void mult_tarlong_helper PARAMS ((tarcell *, tarcell));
void print_tarlong_helper PARAMS ((tarcell *, FILE *));
# define zerop_tarlong(Accumulator) \
zerop_tarlong_helper (&(Accumulator).digit[0])
# define lessp_tarlong(First, Second) \
lessp_tarlong_helper (&(First).digit[0], &(Second).digit[0])
# define clear_tarlong(Accumulator) \
clear_tarlong_helper (&(Accumulator).digit[0])
# define add_to_tarlong(Accumulator, Value) \
add_to_tarlong_helper (&(Accumulator).digit[0], (tarcell) (Value))
# define mult_tarlong(Accumulator, Value) \
mult_tarlong_helper (&(Accumulator).digit[0], (tarcell) (Value))
# define print_tarlong(Accumulator, File) \
print_tarlong_helper (&(Accumulator).digit[0], (File))
#else /* not SUPERDIGIT */
# define zerop_tarlong(Accumulator) \
((Accumulator) == 0)
# define lessp_tarlong(First, Second) \
((First) < (Second))
# define clear_tarlong(Accumulator) \
((Accumulator) = 0)
# define add_to_tarlong(Accumulator, Value) \
((Accumulator) += (Value))
# define mult_tarlong(Accumulator, Value) \
((Accumulator) *= (Value))
# define print_tarlong(Accumulator, File) \
(fprintf ((File), TARLONG_FORMAT, (Accumulator)))
#endif /* not SUPERDIGIT */