2 bigint.c - Manage big positive integer numbers
3 Copyright (c) 1996,2001,5 Martin Schulze <joey@infodrom.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 bigint bigint_add(bigint a, bigint b)
30 unsigned long int tmp;
33 for (i=0; i<BIGINT_LEN; i++) {
34 tmp = a.val[i] + b.val[i];
35 if (tmp >= BIGINT_MAX) {
36 c.val[i] = tmp - BIGINT_MAX;
40 fprintf(stderr, "Overflow in bigint addition.\n");
47 bigint bigint_sub(bigint a, bigint b)
49 unsigned long int tmp;
52 int cmp = bigint_cmp(a,b);
53 bigint rem = bigint_int(0);;
56 fprintf(stderr, "Error in bigint_sub: result is negative.\n");
62 for (i=0;i<BIGINT_LEN;i++) {
63 if (a.val[i] >= b.val[i]) {
64 a.val[i] = a.val[i] - b.val[i];
72 if (t+1 >= BIGINT_LEN) {
73 fprintf(stderr, "Error in bigint_sub.\n");
76 if ( a.val[t+1] == 0 ) {
80 a.val[t+1] = a.val[t+1] - 1;
82 rem = bigint_add(rem, bigint_int(a.val[t]));
83 a.val[t] = BIGINT_MAX - 1;
86 a.val[i] = a.val[i] - tmp;
87 a = bigint_add(a, bigint_int(1));
88 a = bigint_add(a, rem);
96 bigint bigint_int(int num)
102 fprintf(stderr, "Trying to assign negative value to bigint.\n");
106 for (i=0; i<BIGINT_LEN; i++) x.val[i] = 0L;
107 if (num < BIGINT_MAX)
110 x.val[0] = num-BIGINT_MAX;
111 x.val[1] = num/BIGINT_MAX;
117 bigint bigint_string(char *s)
119 char tmp[BIGINT_PREC+1];
124 for (i=0; i<BIGINT_LEN; i++) a.val[i] = 0L;
125 if ((x = (char *)malloc(strlen(s)+1))) {
127 for (i=0; i<BIGINT_LEN; i++) {
130 if (strlen(x) > BIGINT_PREC)
131 cp += (strlen(x) - BIGINT_PREC);
134 sscanf(tmp, "%lu", &a.val[i]);
143 void bigint_sprintf (char *res, char *format, bigint a)
145 char s[(BIGINT_PREC*BIGINT_LEN)+1];
146 char tmp[BIGINT_PREC+1];
150 memset (s, 0, sizeof(s));
151 sprintf(form, "%%0%dlu", BIGINT_PREC);
153 for (;max>0 && !a.val[max-1];max--);
154 if (max == 0) s[0] = '0';
155 for (i=0; i<max; i++) {
157 sprintf(tmp, form, a.val[i]);
159 sprintf(tmp, "%lu", a.val[i]);
160 sprintf (res, "%s%s", tmp, s);
161 sprintf (s, "%s", res);
163 sprintf (res, format, s);
166 int bigint_cmp(bigint a, bigint b)
170 for (i=BIGINT_LEN-1; i>=0; i--) {
171 if (a.val[i] > b.val[i])
173 if (a.val[i] < b.val[i])
175 if (a.val[i] == b.val[i])