1 b3f61791 2004-03-21 devnull #include "os.h"
2 b3f61791 2004-03-21 devnull #include <mp.h>
3 b3f61791 2004-03-21 devnull #include "dat.h"
5 b3f61791 2004-03-21 devnull static int
6 b3f61791 2004-03-21 devnull to64(mpint *b, char *buf, int len)
9 b3f61791 2004-03-21 devnull int n, rv;
12 b3f61791 2004-03-21 devnull n = mptobe(b, nil, 0, &p);
13 b3f61791 2004-03-21 devnull if(n < 0)
14 b3f61791 2004-03-21 devnull return -1;
15 b3f61791 2004-03-21 devnull rv = enc64(buf, len, p, n);
17 b3f61791 2004-03-21 devnull return rv;
20 b3f61791 2004-03-21 devnull static int
21 b3f61791 2004-03-21 devnull to32(mpint *b, char *buf, int len)
23 b3f61791 2004-03-21 devnull uchar *p;
24 b3f61791 2004-03-21 devnull int n, rv;
26 cbeb0b26 2006-04-01 devnull /* leave room for a multiple of 5 buffer size */
27 b3f61791 2004-03-21 devnull n = b->top*Dbytes + 5;
28 b3f61791 2004-03-21 devnull p = malloc(n);
29 b3f61791 2004-03-21 devnull if(p == nil)
30 b3f61791 2004-03-21 devnull return -1;
31 b3f61791 2004-03-21 devnull n = mptobe(b, p, n, nil);
32 b3f61791 2004-03-21 devnull if(n < 0)
33 b3f61791 2004-03-21 devnull return -1;
35 cbeb0b26 2006-04-01 devnull /* round up buffer size, enc32 only accepts a multiple of 5 */
37 b3f61791 2004-03-21 devnull n += 5 - (n%5);
38 b3f61791 2004-03-21 devnull rv = enc32(buf, len, p, n);
40 b3f61791 2004-03-21 devnull return rv;
43 039b8c9a 2005-02-13 devnull static char upper16[] = "0123456789ABCDEF";
44 039b8c9a 2005-02-13 devnull static char lower16[] = "0123456789abcdef";
45 b3f61791 2004-03-21 devnull static int
46 039b8c9a 2005-02-13 devnull to16(mpint *b, char *buf, int len, char *set16)
48 b3f61791 2004-03-21 devnull mpdigit *p, x;
49 b3f61791 2004-03-21 devnull int i, j;
50 b3f61791 2004-03-21 devnull char *out, *eout;
52 b3f61791 2004-03-21 devnull if(len < 1)
53 b3f61791 2004-03-21 devnull return -1;
55 b3f61791 2004-03-21 devnull out = buf;
56 b3f61791 2004-03-21 devnull eout = buf+len;
57 b3f61791 2004-03-21 devnull for(p = &b->p[b->top-1]; p >= b->p; p--){
59 b3f61791 2004-03-21 devnull for(i = Dbits-4; i >= 0; i -= 4){
60 b3f61791 2004-03-21 devnull j = 0xf & (x>>i);
61 b3f61791 2004-03-21 devnull if(j != 0 || out != buf){
62 b3f61791 2004-03-21 devnull if(out >= eout)
63 b3f61791 2004-03-21 devnull return -1;
64 b3f61791 2004-03-21 devnull *out++ = set16[j];
68 b3f61791 2004-03-21 devnull if(out == buf)
69 b3f61791 2004-03-21 devnull *out++ = '0';
70 b3f61791 2004-03-21 devnull if(out >= eout)
71 b3f61791 2004-03-21 devnull return -1;
72 b3f61791 2004-03-21 devnull *out = 0;
73 b3f61791 2004-03-21 devnull return 0;
76 b3f61791 2004-03-21 devnull static char*
77 b3f61791 2004-03-21 devnull modbillion(int rem, ulong r, char *out, char *buf)
79 b3f61791 2004-03-21 devnull ulong rr;
82 b3f61791 2004-03-21 devnull for(i = 0; i < 9; i++){
83 b3f61791 2004-03-21 devnull rr = r%10;
85 b3f61791 2004-03-21 devnull if(out <= buf)
86 b3f61791 2004-03-21 devnull return nil;
87 b3f61791 2004-03-21 devnull *--out = '0' + rr;
88 b3f61791 2004-03-21 devnull if(rem == 0 && r == 0)
91 b3f61791 2004-03-21 devnull return out;
94 b3f61791 2004-03-21 devnull static int
95 b3f61791 2004-03-21 devnull to10(mpint *b, char *buf, int len)
97 b3f61791 2004-03-21 devnull mpint *d, *r, *billion;
98 b3f61791 2004-03-21 devnull char *out;
100 b3f61791 2004-03-21 devnull if(len < 1)
101 b3f61791 2004-03-21 devnull return -1;
103 b3f61791 2004-03-21 devnull d = mpcopy(b);
104 b3f61791 2004-03-21 devnull r = mpnew(0);
105 b3f61791 2004-03-21 devnull billion = uitomp(1000000000, nil);
106 b3f61791 2004-03-21 devnull out = buf+len;
107 b3f61791 2004-03-21 devnull *--out = 0;
109 b3f61791 2004-03-21 devnull mpdiv(d, billion, d, r);
110 b3f61791 2004-03-21 devnull out = modbillion(d->top, r->p[0], out, buf);
111 b3f61791 2004-03-21 devnull if(out == nil)
113 b3f61791 2004-03-21 devnull } while(d->top != 0);
114 b3f61791 2004-03-21 devnull mpfree(d);
115 b3f61791 2004-03-21 devnull mpfree(r);
116 b3f61791 2004-03-21 devnull mpfree(billion);
118 b3f61791 2004-03-21 devnull if(out == nil)
119 b3f61791 2004-03-21 devnull return -1;
120 b3f61791 2004-03-21 devnull len -= out-buf;
121 b3f61791 2004-03-21 devnull if(out != buf)
122 b3f61791 2004-03-21 devnull memmove(buf, out, len);
123 b3f61791 2004-03-21 devnull return 0;
126 039b8c9a 2005-02-13 devnull static char*
127 039b8c9a 2005-02-13 devnull _mptoa(mpint *b, int base, char *buf, int len, char *set16)
129 b3f61791 2004-03-21 devnull char *out;
130 b3f61791 2004-03-21 devnull int rv, alloced;
132 b3f61791 2004-03-21 devnull alloced = 0;
133 b3f61791 2004-03-21 devnull if(buf == nil){
134 b3f61791 2004-03-21 devnull len = ((b->top+1)*Dbits+2)/3 + 1;
135 b3f61791 2004-03-21 devnull buf = malloc(len);
136 b3f61791 2004-03-21 devnull if(buf == nil)
137 b3f61791 2004-03-21 devnull return nil;
138 b3f61791 2004-03-21 devnull alloced = 1;
141 b3f61791 2004-03-21 devnull if(len < 2)
142 b3f61791 2004-03-21 devnull return nil;
144 b3f61791 2004-03-21 devnull out = buf;
145 b3f61791 2004-03-21 devnull if(b->sign < 0){
146 b3f61791 2004-03-21 devnull *out++ = '-';
149 b3f61791 2004-03-21 devnull switch(base){
150 b3f61791 2004-03-21 devnull case 64:
151 b3f61791 2004-03-21 devnull rv = to64(b, out, len);
153 b3f61791 2004-03-21 devnull case 32:
154 b3f61791 2004-03-21 devnull rv = to32(b, out, len);
156 b3f61791 2004-03-21 devnull default:
157 b3f61791 2004-03-21 devnull case 16:
158 039b8c9a 2005-02-13 devnull rv = to16(b, out, len, set16);
160 b3f61791 2004-03-21 devnull case 10:
161 b3f61791 2004-03-21 devnull rv = to10(b, out, len);
164 b3f61791 2004-03-21 devnull if(rv < 0){
165 b3f61791 2004-03-21 devnull if(alloced)
166 b3f61791 2004-03-21 devnull free(buf);
167 b3f61791 2004-03-21 devnull return nil;
169 b3f61791 2004-03-21 devnull return buf;
173 039b8c9a 2005-02-13 devnull mptoa(mpint *b, int base, char *buf, int len)
175 039b8c9a 2005-02-13 devnull return _mptoa(b, base, buf, len, upper16);
179 039b8c9a 2005-02-13 devnull mpfmt(Fmt *fmt)
181 039b8c9a 2005-02-13 devnull mpint *b;
182 039b8c9a 2005-02-13 devnull char *p;
183 039b8c9a 2005-02-13 devnull char *set16;
185 039b8c9a 2005-02-13 devnull b = va_arg(fmt->args, mpint*);
186 039b8c9a 2005-02-13 devnull if(b == nil)
187 039b8c9a 2005-02-13 devnull return fmtstrcpy(fmt, "*");
189 039b8c9a 2005-02-13 devnull set16 = upper16;
190 039b8c9a 2005-02-13 devnull if(fmt->flags & FmtLong)
191 039b8c9a 2005-02-13 devnull set16 = lower16;
192 039b8c9a 2005-02-13 devnull p = _mptoa(b, fmt->prec, nil, 0, set16);
193 039b8c9a 2005-02-13 devnull fmt->flags &= ~FmtPrec;
195 039b8c9a 2005-02-13 devnull if(p == nil)
196 039b8c9a 2005-02-13 devnull return fmtstrcpy(fmt, "*");
198 039b8c9a 2005-02-13 devnull fmtstrcpy(fmt, p);
199 039b8c9a 2005-02-13 devnull free(p);
200 039b8c9a 2005-02-13 devnull return 0;