38511aa64332b8fdf7e87034a1f8f4833d049c8d
[infodrom/dtaus] / bigint.c
1 /*
2     bigint.c - Manage big positive integer numbers
3     Copyright (c) 1996,2001  Martin Schulze <joey@artis.uni-oldenburg.de>
4
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.
9
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.
14
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.
18
19     $Id$
20  */
21
22 #include "bigint.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include <malloc.h>
26
27 bigint bigint_add(bigint a, bigint b)
28 {
29   int i;
30   unsigned long int tmp;
31   bigint c;
32
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;
37       if (i<BIGINT_LEN)
38         a.val[i+1]++;
39       else
40         fprintf(stderr, "Overflow in bigint addition.");
41     } else
42       c.val[i] = tmp;
43   }
44   return c;
45 }
46
47 bigint bigint_sub(bigint a, bigint b)
48 {
49   /* FIXME */
50   fprintf (stderr, "bigint_sub not supported yet.\n");
51   return a;
52 }
53
54 bigint bigint_int(int num)
55 {
56   bigint x;
57   int i;
58
59   for (i=0; i<BIGINT_LEN; i++) x.val[i] = 0L;
60   x.val[0] = num;
61   x.val[1] = 0;
62   return x;
63 }
64
65 bigint bigint_string(char *s)
66 {
67   char tmp[BIGINT_PREC+1];
68   bigint a;
69   int i;
70   char *cp, *x;
71
72   for (i=0; i<BIGINT_LEN; i++) a.val[i] = 0L;
73   if ((x = (char *)malloc(strlen(s)+1))) {
74     strcpy(x, s);
75     for (i=0; i<BIGINT_LEN; i++) {
76       if (strlen(x)) {
77         cp = x;
78         if (strlen(x) > BIGINT_PREC)
79           cp += (strlen(x) - BIGINT_PREC);
80         strcpy(tmp, cp);
81         *cp = '\0';
82         sscanf(tmp, "%lu", &a.val[i]);
83       }
84     }
85     free (x);
86   }
87
88   return a;
89 }
90
91 void bigint_sprintf (char *res, char *format, bigint a)
92 {
93   char s[(BIGINT_PREC*BIGINT_LEN)+1];
94   char tmp[BIGINT_PREC+1];
95   char form[6];
96   int i, max;
97
98   memset (s, 0, sizeof(s));
99   sprintf(form, "%%0%dlu", BIGINT_PREC);
100   max = BIGINT_LEN;
101   for (;max>0 && !a.val[max-1];max--);
102   for (i=0; i<max; i++) {
103     if (i<max-1)
104       sprintf(tmp, form, a.val[i]);
105     else
106       sprintf(tmp, "%lu", a.val[i]);
107     sprintf (res, "%s%s", tmp, s);
108     sprintf (s, "%s", res);
109   }
110   sprintf (res, format, s);
111 }