Subversion Repositories planix.SVN

Rev

Rev 22 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 22 Rev 26
Line 3... Line 3...
3
#include "dat.h"
3
#include "dat.h"
4
 
4
 
5
static mpdigit _mptwodata[1] = { 2 };
5
static mpdigit _mptwodata[1] = { 2 };
6
static mpint _mptwo =
6
static mpint _mptwo =
7
{
7
{
8
	1,
-
 
9
	1,
-
 
10
	1,
8
	1, 1, 1,
11
	_mptwodata,
9
	_mptwodata,
12
	MPstatic
10
	MPstatic|MPnorm
13
};
11
};
14
mpint *mptwo = &_mptwo;
12
mpint *mptwo = &_mptwo;
15
 
13
 
16
static mpdigit _mponedata[1] = { 1 };
14
static mpdigit _mponedata[1] = { 1 };
17
static mpint _mpone =
15
static mpint _mpone =
18
{
16
{
19
	1,
-
 
20
	1,
-
 
21
	1,
17
	1, 1, 1,
22
	_mponedata,
18
	_mponedata,
23
	MPstatic
19
	MPstatic|MPnorm
24
};
20
};
25
mpint *mpone = &_mpone;
21
mpint *mpone = &_mpone;
26
 
22
 
27
static mpdigit _mpzerodata[1] = { 0 };
23
static mpdigit _mpzerodata[1] = { 0 };
28
static mpint _mpzero =
24
static mpint _mpzero =
29
{
25
{
30
	1,
-
 
31
	1,
-
 
32
	0,
26
	1, 1, 0,
33
	_mpzerodata,
27
	_mpzerodata,
34
	MPstatic
28
	MPstatic|MPnorm
35
};
29
};
36
mpint *mpzero = &_mpzero;
30
mpint *mpzero = &_mpzero;
37
 
31
 
38
static int mpmindigits = 33;
32
static int mpmindigits = 33;
39
 
33
 
Line 55... Line 49...
55
	mpint *b;
49
	mpint *b;
56
 
50
 
57
	if(n < 0)
51
	if(n < 0)
58
		sysfatal("mpsetminbits: n < 0");
52
		sysfatal("mpsetminbits: n < 0");
59
 
53
 
60
	b = mallocz(sizeof(mpint), 1);
-
 
61
	setmalloctag(b, getcallerpc(&n));
-
 
62
	if(b == nil)
-
 
63
		sysfatal("mpnew: %r");
-
 
64
	n = DIGITS(n);
54
	n = DIGITS(n);
65
	if(n < mpmindigits)
55
	if(n < mpmindigits)
66
		n = mpmindigits;
56
		n = mpmindigits;
67
	b->p = (mpdigit*)mallocz(n*Dbytes, 1);
57
	b = mallocz(sizeof(mpint) + n*Dbytes, 1);
68
	if(b->p == nil)
58
	if(b == nil)
69
		sysfatal("mpnew: %r");
59
		sysfatal("mpnew: %r");
-
 
60
	setmalloctag(b, getcallerpc(&n));
-
 
61
	b->p = (mpdigit*)&b[1];
70
	b->size = n;
62
	b->size = n;
71
	b->sign = 1;
63
	b->sign = 1;
-
 
64
	b->flags = MPnorm;
72
 
65
 
73
	return b;
66
	return b;
74
}
67
}
75
 
68
 
76
// guarantee at least n significant bits
69
// guarantee at least n significant bits
Line 81... Line 74...
81
 
74
 
82
	n = DIGITS(m);
75
	n = DIGITS(m);
83
	if(b->size >= n){
76
	if(b->size >= n){
84
		if(b->top >= n)
77
		if(b->top >= n)
85
			return;
78
			return;
-
 
79
	} else {
-
 
80
		if(b->p == (mpdigit*)&b[1]){
-
 
81
			b->p = (mpdigit*)mallocz(n*Dbytes, 0);
-
 
82
			if(b->p == nil)
-
 
83
				sysfatal("mpbits: %r");
-
 
84
			memmove(b->p, &b[1], Dbytes*b->top);
86
		memset(&b->p[b->top], 0, Dbytes*(n - b->top));
85
			memset(&b[1], 0, Dbytes*b->size);
-
 
86
		} else {
-
 
87
			b->p = (mpdigit*)realloc(b->p, n*Dbytes);
87
		b->top = n;
88
			if(b->p == nil)
-
 
89
				sysfatal("mpbits: %r");
-
 
90
		}
88
		return;
91
		b->size = n;
89
	}
92
	}
90
	b->p = (mpdigit*)realloc(b->p, n*Dbytes);
-
 
91
	if(b->p == nil)
-
 
92
		sysfatal("mpbits: %r");
-
 
93
	memset(&b->p[b->top], 0, Dbytes*(n - b->top));
93
	memset(&b->p[b->top], 0, Dbytes*(n - b->top));
94
	b->size = n;
-
 
95
	b->top = n;
94
	b->top = n;
-
 
95
	b->flags &= ~MPnorm;
96
}
96
}
97
 
97
 
98
void
98
void
99
mpfree(mpint *b)
99
mpfree(mpint *b)
100
{
100
{
101
	if(b == nil)
101
	if(b == nil)
102
		return;
102
		return;
103
	if(b->flags & MPstatic)
103
	if(b->flags & MPstatic)
104
		sysfatal("freeing mp constant");
104
		sysfatal("freeing mp constant");
105
	memset(b->p, 0, b->size*Dbytes);	// information hiding
105
	memset(b->p, 0, b->size*Dbytes);
-
 
106
	if(b->p != (mpdigit*)&b[1])
106
	free(b->p);
107
		free(b->p);
107
	free(b);
108
	free(b);
108
}
109
}
109
 
110
 
110
void
111
mpint*
111
mpnorm(mpint *b)
112
mpnorm(mpint *b)
112
{
113
{
113
	int i;
114
	int i;
114
 
115
 
-
 
116
	if(b->flags & MPtimesafe){
-
 
117
		assert(b->sign == 1);
-
 
118
		b->flags &= ~MPnorm;
-
 
119
		return b;
-
 
120
	}
115
	for(i = b->top-1; i >= 0; i--)
121
	for(i = b->top-1; i >= 0; i--)
116
		if(b->p[i] != 0)
122
		if(b->p[i] != 0)
117
			break;
123
			break;
118
	b->top = i+1;
124
	b->top = i+1;
119
	if(b->top == 0)
125
	if(b->top == 0)
120
		b->sign = 1;
126
		b->sign = 1;
-
 
127
	b->flags |= MPnorm;
-
 
128
	return b;
121
}
129
}
122
 
130
 
123
mpint*
131
mpint*
124
mpcopy(mpint *old)
132
mpcopy(mpint *old)
125
{
133
{
126
	mpint *new;
134
	mpint *new;
127
 
135
 
128
	new = mpnew(Dbits*old->size);
136
	new = mpnew(Dbits*old->size);
-
 
137
	setmalloctag(new, getcallerpc(&old));
129
	new->top = old->top;
138
	new->sign = old->sign;
130
	new->sign = old->sign;
139
	new->top = old->top;
-
 
140
	new->flags = old->flags & ~(MPstatic|MPfield);
131
	memmove(new->p, old->p, Dbytes*old->top);
141
	memmove(new->p, old->p, Dbytes*old->top);
132
	return new;
142
	return new;
133
}
143
}
134
 
144
 
135
void
145
void
136
mpassign(mpint *old, mpint *new)
146
mpassign(mpint *old, mpint *new)
137
{
147
{
-
 
148
	if(new == nil || old == new)
-
 
149
		return;
-
 
150
	new->top = 0;
138
	mpbits(new, Dbits*old->top);
151
	mpbits(new, Dbits*old->top);
139
	new->sign = old->sign;
152
	new->sign = old->sign;
140
	new->top = old->top;
153
	new->top = old->top;
-
 
154
	new->flags &= ~MPnorm;
-
 
155
	new->flags |= old->flags & ~(MPstatic|MPfield);
141
	memmove(new->p, old->p, Dbytes*old->top);
156
	memmove(new->p, old->p, Dbytes*old->top);
142
}
157
}
143
 
158
 
144
// number of significant bits in mantissa
159
// number of significant bits in mantissa
145
int
160
int
146
mpsignif(mpint *n)
161
mpsignif(mpint *n)
147
{
162
{
148
	int i, j;
163
	int i, j;
149
	mpdigit d;
164
	mpdigit d;
150
 
165
 
Line 165... Line 180...
165
mplowbits0(mpint *n)
180
mplowbits0(mpint *n)
166
{
181
{
167
	int k, bit, digit;
182
	int k, bit, digit;
168
	mpdigit d;
183
	mpdigit d;
169
 
184
 
-
 
185
	assert(n->flags & MPnorm);
170
	if(n->top==0)
186
	if(n->top==0)
171
		return 0;
187
		return 0;
172
	k = 0;
188
	k = 0;
173
	bit = 0;
189
	bit = 0;
174
	digit = 0;
190
	digit = 0;
Line 185... Line 201...
185
			bit = 0;
201
			bit = 0;
186
		}
202
		}
187
	}
203
	}
188
	return k;
204
	return k;
189
}
205
}
190
 
-