Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/trunk/sys/src/libmp/test/ld.c – Rev 26

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
26 7u83 1
#include <u.h>
2
#include <libc.h>
3
#include <mp.h>
4
#include <libsec.h>
5
#include "dat.h"
6
#include "fns.h"
7
 
8
ldint _ldzero = {1, (u8int*)"\0"};
9
ldint _ldone = {2, (u8int*)"\1\0"};
10
ldint *ldzero = &_ldzero;
11
ldint *ldone = &_ldone;
12
 
13
int
14
ldget(ldint *a, int n)
15
{
16
	if(n < 0) return 0;
17
	if(n >= a->n) return a->b[a->n - 1]&1;
18
	return a->b[n]&1;
19
}
20
 
21
void
22
ldbits(ldint *a, int n)
23
{
24
	a->b = realloc(a->b, n);
25
	a->n = n;
26
}
27
 
28
ldint *
29
ldnorm(ldint *a)
30
{
31
	int i;
32
 
33
	if(a->n > 0){
34
		for(i = a->n - 2; i >= 0; i--)
35
			if(a->b[i] != a->b[a->n-1])
36
				break;
37
		ldbits(a, i + 2);
38
	}else{
39
		ldbits(a, 1);
40
		a->b[0] = 0;
41
	}
42
	return a;
43
}
44
 
45
void
46
ldneg(ldint *a)
47
{
48
	int i, c, s, z;
49
 
50
	c = 1;
51
	s = a->b[a->n - 1];
52
	z = 1;
53
	for(i = 0; i < a->n; i++){
54
		if(a->b[i]) z = 0;
55
		c += 1 ^ a->b[i] & 1;
56
		a->b[i] = c & 1;
57
		c >>= 1;
58
	}
59
	if(!z && s == a->b[a->n - 1]){
60
		ldbits(a, a->n + 1);
61
		a->b[a->n - 1] = !s;
62
	}
63
}
64
 
65
int
66
max(int a, int b)
67
{
68
	return a>b? a : b;
69
}
70
 
71
ldint *
72
ldnew(int n)
73
{
74
	ldint *a;
75
 
76
	a = malloc(sizeof(ldint));
77
	if(n <= 0) n = 1;
78
	a->b = malloc(n);
79
	a->n = n;
80
	return a;
81
}
82
 
83
void
84
ldfree(ldint *a)
85
{
86
	if(a == nil) return;
87
	free(a->b);
88
	free(a);
89
}
90
 
91
void
92
ldsanity(ldint *a)
93
{
94
	int i;
95
 
96
	assert(a->n > 0);
97
	for(i = 0; i < a->n; i++)
98
		assert(a->b[i] < 2);
99
}
100
 
101
ldint *
102
ldrand(int n, ldint *a)
103
{
104
	int i;
105
 
106
	if(a == nil)
107
		a = ldnew(n);
108
	else
109
		ldbits(a, n);
110
	for(i = 0; i < n; i++)
111
		a->b[i] = rand() & 1;
112
	return a;
113
}
114
 
115
mpint *
116
ldtomp(ldint *a, mpint *b)
117
{
118
	int s, c, i;
119
 
120
	if(b == nil)
121
		b = mpnew(0);
122
	mpbits(b, a->n);
123
	s = a->b[a->n - 1] & 1;
124
	b->sign = 1 - 2 * s;
125
	c = s;
126
	memset(b->p, 0, (a->n + Dbits - 1) / Dbits * Dbytes);
127
	for(i = 0; i < a->n; i++){
128
		c += s ^ a->b[i] & 1;
129
		b->p[i / Dbits] |= (mpdigit)(c & 1) << (i & Dbits - 1);
130
		c >>= 1;
131
	}
132
	b->top = (a->n + Dbits - 1) / Dbits;
133
	mpnorm(b);
134
	return b;
135
}
136
 
137
void
138
mptold(mpint *b, ldint *a)
139
{
140
	int i, j, n, c;
141
 
142
	n = mpsignif(b) + 1;
143
	ldbits(a, n);
144
	memset(a->b, 0, n);
145
	for(i = 0; i <= b->top; i++)
146
		for(j = 0; j < Dbits; j++)
147
			if(Dbits * i + j < n)
148
				a->b[Dbits * i + j] = b->p[i] >> j & 1;
149
	if(b->sign < 0){
150
		c = 1;
151
		for(i = 0; i < a->n; i++){
152
			c += 1 ^ a->b[i] & 1;
153
			a->b[i] = c & 1;
154
			c >>= 1;
155
		}
156
	}	
157
}
158
 
159
ldint *
160
itold(int n, ldint *a)
161
{
162
	int i;
163
 
164
	if(a == nil)
165
		a = ldnew(sizeof(n)*8);
166
	else
167
		ldbits(a, sizeof(n)*8);
168
	for(i = 0; i < sizeof(n)*8; i++)
169
		a->b[i] = n >> i & 1;
170
	ldnorm(a);
171
	return a;
172
}
173
 
174
ldint *
175
pow2told(int n, ldint *a)
176
{
177
	int k;
178
 
179
	k = abs(n);
180
	if(a == nil)
181
		a = ldnew(k+2);
182
	else
183
		ldbits(a, k+2);
184
	memset(a->b, 0, k+2);
185
	a->b[k] = 1;
186
	if(n < 0) ldneg(a);
187
	ldnorm(a);
188
	return a;
189
}
190
 
191
int
192
ldfmt(Fmt *f)
193
{
194
	ldint *a;
195
	char *b, *p;
196
	int i, d, s, c;
197
 
198
	a = va_arg(f->args, ldint *);
199
	d = (a->n + 3) / 4;
200
	b = calloc(1, d + 1);
201
	c = s = a->b[a->n - 1];
202
	for(i = 0; i < a->n; i++){
203
		c += s^ldget(a, i);
204
		b[d - 1 - (i >> 2)] |= (c & 1) << (i & 3);
205
		c >>= 1;
206
	}
207
	for(i = 0; i < d; i++)
208
		b[i] = "0123456789ABCDEF"[b[i]];
209
	p = b;
210
	while(*p == '0' && p[1] != 0) p++;
211
	if(a->b[a->n - 1]) fmtrune(f, '-');
212
	fmtprint(f, "0x%s", p);
213
	free(b);
214
	return 0;
215
}
216
 
217
int
218
ldcmp(ldint *a, ldint *b)
219
{
220
	int x, y;
221
	int i, r;
222
 
223
	r = max(a->n, b->n);
224
	if(a->b[a->n-1] != b->b[b->n-1])
225
		return b->b[b->n - 1] - a->b[a->n - 1];
226
	for(i = r - 1; --i >= 0; ){
227
		x = ldget(a, i);
228
		y = ldget(b, i);
229
		if(x != y)
230
			return x - y;
231
	}
232
	return 0;
233
}
234
 
235
int
236
ldmagcmp(ldint *a, ldint *b)
237
{
238
	int s1, s2, r;
239
 
240
	s1 = a->b[a->n - 1];
241
	s2 = b->b[b->n - 1];
242
	if(s1) ldneg(a);
243
	if(s2) ldneg(b);
244
	r = ldcmp(a, b);
245
	if(s1) ldneg(a);
246
	if(s2) ldneg(b);
247
	return r;
248
}
249
 
250
int
251
ldmpeq(ldint *a, mpint *b)
252
{
253
	int i, c;
254
 
255
	if(b->sign > 0){
256
		for(i = 0; i < b->top * Dbits; i++)
257
			if(ldget(a, i) != (b->p[i / Dbits] >> (i & Dbits - 1) & 1))
258
				return 0;
259
		for(; i < a->n; i++)
260
			if(a->b[i] != 0)
261
				return 0;
262
		return 1;
263
	}else{
264
		c = 1;
265
		for(i = 0; i < b->top * Dbits; i++){
266
			c += !ldget(a, i);
267
			if((c & 1) != (b->p[i / Dbits] >> (i & Dbits - 1) & 1))
268
				return 0;
269
			c >>= 1;
270
		}
271
		for(; i < a->n; i++)
272
			if(a->b[i] != 1)
273
				return 0;
274
		return 1;
275
	}
276
}
277
 
278
void
279
mptarget(mpint *r)
280
{
281
	int n;
282
 
283
	n = nrand(16);
284
	mpbits(r, n * Dbits);
285
	r->top = n;
286
	prng((void *) r->p, n * Dbytes);
287
	r->sign = 1 - 2 * (rand() & 1);
288
}
289
 
290
void
291
ldadd(ldint *a, ldint *b, ldint *q)
292
{
293
	int r, i, c;
294
 
295
	r = max(a->n, b->n) + 1;
296
	ldbits(q, r);
297
	c = 0;
298
	for(i = 0; i < r; i++){
299
		c += ldget(a, i) + ldget(b, i);
300
		q->b[i] = c & 1;
301
		c >>= 1;
302
	}
303
	ldnorm(q);
304
}
305
 
306
void
307
ldmagadd(ldint *a, ldint *b, ldint *q)
308
{
309
	int i, r, s1, s2, c1, c2, co;
310
 
311
	r = max(a->n, b->n) + 2;
312
	ldbits(q, r);
313
	co = 0;
314
	s1 = c1 = a->b[a->n - 1] & 1;
315
	s2 = c2 = b->b[b->n - 1] & 1;
316
	for(i = 0; i < r; i++){
317
		c1 += s1 ^ ldget(a, i) & 1;
318
		c2 += s2 ^ ldget(b, i) & 1;
319
		co += (c1 & 1) + (c2 & 1);
320
		q->b[i] = co & 1;
321
		co >>= 1;
322
		c1 >>= 1;
323
		c2 >>= 1;
324
	}
325
	ldnorm(q);
326
}
327
 
328
void
329
ldmagsub(ldint *a, ldint *b, ldint *q)
330
{
331
	int i, r, s1, s2, c1, c2, co;
332
 
333
	r = max(a->n, b->n) + 2;
334
	ldbits(q, r);
335
	co = 0;
336
	s1 = c1 = a->b[a->n - 1] & 1;
337
	s2 = c2 = 1 ^ b->b[b->n - 1] & 1;
338
	for(i = 0; i < r; i++){
339
		c1 += s1 ^ ldget(a, i) & 1;
340
		c2 += s2 ^ ldget(b, i) & 1;
341
		co += (c1 & 1) + (c2 & 1);
342
		q->b[i] = co & 1;
343
		co >>= 1;
344
		c1 >>= 1;
345
		c2 >>= 1;
346
	}
347
	ldnorm(q);
348
}
349
 
350
void
351
ldsub(ldint *a, ldint *b, ldint *q)
352
{
353
	int r, i, c;
354
 
355
	r = max(a->n, b->n) + 1;
356
	ldbits(q, r);
357
	c = 1;
358
	for(i = 0; i < r; i++){
359
		c += ldget(a, i) + (1^ldget(b, i));
360
		q->b[i] = c & 1;
361
		c >>= 1;
362
	}
363
	ldnorm(q);
364
}
365
 
366
void
367
ldmul(ldint *a, ldint *b, ldint *q)
368
{
369
	int c1, c2, co, s1, s2, so, i, j;
370
 
371
	c1 = s1 = a->b[a->n - 1] & 1;
372
	s2 = b->b[b->n - 1] & 1;
373
	so = s1 ^ s2;
374
	ldbits(q, a->n + b->n + 1);
375
	memset(q->b, 0, a->n + b->n + 1);
376
	for(i = 0; i < a->n; i++){
377
		c1 += s1 ^ a->b[i] & 1;
378
		if((c1 & 1) != 0){
379
			c2 = s2;
380
			for(j = 0; j < b->n; j++){
381
				c2 += (s2 ^ b->b[j] & 1) + q->b[i + j];
382
				q->b[i + j] = c2 & 1;
383
				c2 >>= 1;
384
			}
385
			for(; c2 > 0; j++){
386
				assert(i + j < q->n);
387
				q->b[i + j] = c2 & 1;
388
				c2 >>= 1;
389
			}
390
		}
391
		c1 >>= 1;
392
	}
393
	co = so;
394
	for(i = 0; i < q->n; i++){
395
		co += so ^ q->b[i];
396
		q->b[i] = co & 1;
397
		co >>= 1;
398
	}
399
}
400
 
401
void
402
lddiv(ldint *a, ldint *b, ldint *q, ldint *r)
403
{
404
	int n, i, j, c, s;
405
 
406
	n = max(a->n, b->n) + 1;
407
	ldbits(q, n);
408
	ldbits(r, n);
409
	memset(r->b, 0, n);
410
	c = s = a->b[a->n-1];
411
	for(i = 0; i < n; i++){
412
		c += s ^ ldget(a, i);
413
		q->b[i] = c & 1;
414
		c >>= 1;
415
	}
416
	for(i = 0; i < n; i++){
417
		for(j = n-1; --j >= 0; )
418
			r->b[j + 1] = r->b[j];
419
		r->b[0] = q->b[n - 1];
420
		for(j = n-1; --j >= 0; )
421
			q->b[j + 1] = q->b[j];
422
		q->b[0] = !r->b[n - 1];
423
		c = s = r->b[n - 1] == b->b[b->n - 1];
424
		for(j = 0; j < n; j++){
425
			c += r->b[j] + (s ^ ldget(b, j));
426
			r->b[j] = c & 1;
427
			c >>= 1;
428
		}
429
	}
430
	for(j = n-1; --j >= 0; )
431
		q->b[j + 1] = q->b[j];
432
	q->b[0] = 1;
433
	if(r->b[r->n - 1]){
434
		c = 0;
435
		for(j = 0; j < n; j++){
436
			c += 1 + q->b[j];
437
			q->b[j] = c & 1;
438
			c >>= 1;
439
		}
440
		c = s = b->b[b->n - 1];
441
		for(j = 0; j < n; j++){
442
			c += r->b[j] + (s ^ ldget(b, j));
443
			r->b[j] = c & 1;
444
			c >>= 1;
445
		}
446
	}
447
	c = s = a->b[a->n-1] ^ b->b[b->n-1];
448
	for(j = 0; j < n; j++){
449
		c += s ^ q->b[j];
450
		q->b[j] = c & 1;
451
		c >>= 1;
452
	}
453
	c = s = a->b[a->n-1];
454
	for(j = 0; j < n; j++){
455
		c += s ^ r->b[j];
456
		r->b[j] = c & 1;
457
		c >>= 1;
458
	}
459
	ldnorm(q);
460
	ldnorm(r);
461
}
462
 
463
void
464
lddiv_(ldint *a, ldint *b, ldint *q, ldint *r)
465
{
466
	if(ldmpeq(b, mpzero)){
467
		memset(q->b, 0, q->n);
468
		memset(r->b, 0, r->n);
469
		return;
470
	}
471
	lddiv(a, b, q, r);
472
}
473
 
474
void
475
mpdiv_(mpint *a, mpint *b, mpint *q, mpint *r)
476
{
477
	if(mpcmp(b, mpzero) == 0){
478
		mpassign(mpzero, q);
479
		mpassign(mpzero, r);
480
		return;
481
	}
482
	mpdiv(a, b, q, r);
483
}
484
 
485
void
486
ldand(ldint *a, ldint *b, ldint *q)
487
{
488
	int r, i;
489
 
490
	r = max(a->n, b->n);
491
	ldbits(q, r);
492
	for(i = 0; i < r; i++)
493
		q->b[i] = ldget(a, i) & ldget(b, i);
494
	ldnorm(q);
495
}
496
 
497
void
498
ldbic(ldint *a, ldint *b, ldint *q)
499
{
500
	int r, i;
501
 
502
	r = max(a->n, b->n);
503
	ldbits(q, r);
504
	for(i = 0; i < r; i++)
505
		q->b[i] = ldget(a, i) & ~ldget(b, i);
506
	ldnorm(q);
507
}
508
 
509
void
510
ldor(ldint *a, ldint *b, ldint *q)
511
{
512
	int r, i;
513
 
514
	r = max(a->n, b->n);
515
	ldbits(q, r);
516
	for(i = 0; i < r; i++)
517
		q->b[i] = ldget(a, i) | ldget(b, i);
518
	ldnorm(q);
519
}
520
 
521
void
522
ldxor(ldint *a, ldint *b, ldint *q)
523
{
524
	int r, i;
525
 
526
	r = max(a->n, b->n);
527
	ldbits(q, r);
528
	for(i = 0; i < r; i++)
529
		q->b[i] = ldget(a, i) ^ ldget(b, i);
530
	ldnorm(q);
531
}
532
 
533
void
534
ldleft(ldint *a, int n, ldint *b)
535
{
536
	int i, c;
537
 
538
	if(n < 0){
539
		if(a->n <= -n){
540
			b->n = 0;
541
			ldnorm(b);
542
			return;
543
		}
544
		c = 0;
545
		if(a->b[a->n - 1])
546
			for(i = 0; i < -n; i++)
547
				if(a->b[i]){
548
					c = 1;
549
					break;
550
				}
551
		ldbits(b, a->n + n);
552
		for(i = 0; i < a->n + n; i++){
553
			c += a->b[i - n] & 1;
554
			b->b[i] = c & 1;
555
			c >>= 1;
556
		}
557
	}else{
558
		ldbits(b, a->n + n);
559
		memmove(b->b + n, a->b, a->n);
560
		memset(b->b, 0, n);
561
	}
562
	ldnorm(b);
563
}
564
 
565
void
566
ldright(ldint *a, int n, ldint *b)
567
{
568
	ldleft(a, -n, b);
569
}
570
 
571
void
572
ldasr(ldint *a, int n, ldint *b)
573
{
574
	if(n < 0){
575
		ldleft(a, -n, b);
576
		return;
577
	}
578
	if(a->n <= n){
579
		ldbits(b, 1);
580
		b->b[0] = a->b[a->n - 1];
581
		return;
582
	}
583
	ldbits(b, a->n - n);
584
	memmove(b->b, a->b + n, a->n - n);
585
	ldnorm(b);
586
}
587
 
588
void
589
ldtrunc(ldint *a, int n, ldint *b)
590
{
591
	ldbits(b, n+1);
592
	b->b[n] = 0;
593
	if(a->n >= n)
594
		memmove(b->b, a->b, n);
595
	else{
596
		memmove(b->b, a->b, a->n);
597
		memset(b->b + a->n, a->b[a->n - 1], n - a->n);
598
	}
599
	ldnorm(b);
600
}
601
 
602
void
603
ldxtend(ldint *a, int n, ldint *b)
604
{
605
	ldbits(b, n);
606
	if(a->n >= n)
607
		memmove(b->b, a->b, n);
608
	else{
609
		memmove(b->b, a->b, a->n);
610
		memset(b->b + a->n, a->b[a->n - 1], n - a->n);
611
	}
612
	ldnorm(b);
613
}
614
 
615
void
616
ldnot(ldint *a, ldint *b)
617
{
618
	int i;
619
 
620
	ldbits(b, a->n);
621
	for(i = 0; i < a->n; i++)
622
		b->b[i] = a->b[i] ^ 1;
623
}
624
 
625
u32int xorshift(u32int *state)
626
{
627
	u32int x = *state;
628
	x ^= x << 13;
629
	x ^= x >> 17;
630
	x ^= x << 5;
631
	*state = x;
632
	return x;
633
}
634
 
635
void
636
testgen(int i, ldint *a)
637
{
638
	u32int state;
639
	u32int r;
640
	int j;
641
 
642
	if(i < 257)
643
		itold(i-128, a);
644
	else if(i < 514)
645
		pow2told(i-385, a);
646
	else{
647
		state = i;
648
		xorshift(&state);
649
		xorshift(&state);
650
		xorshift(&state);
651
		ldbits(a, Dbits * (1 + (xorshift(&state) & 15)));
652
		SET(r);
653
		for(j = 0; j < a->n; j++){
654
			if((j & 31) == 0)
655
				r = xorshift(&state);
656
			a->b[j] = r & 1;
657
			r >>= 1;
658
		}
659
	}
660
}