OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file contains operations on unsigned multi-precision integers. | 5 // This file contains operations on unsigned multi-precision integers. |
6 // These are the building blocks for the operations on signed integers | 6 // These are the building blocks for the operations on signed integers |
7 // and rationals. | 7 // and rationals. |
8 | 8 |
9 // This package implements multi-precision arithmetic (big numbers). | 9 // This package implements multi-precision arithmetic (big numbers). |
10 // The following numeric types are supported: | 10 // The following numeric types are supported: |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 // len(uIn) >= len(v) | 295 // len(uIn) >= len(v) |
296 func divLargeNN(z, z2, uIn, v []Word) (q, r []Word) { | 296 func divLargeNN(z, z2, uIn, v []Word) (q, r []Word) { |
297 n := len(v) | 297 n := len(v) |
298 m := len(uIn) - len(v) | 298 m := len(uIn) - len(v) |
299 | 299 |
300 u := makeN(z2, len(uIn)+1, false) | 300 u := makeN(z2, len(uIn)+1, false) |
301 qhatv := make([]Word, len(v)+1) | 301 qhatv := make([]Word, len(v)+1) |
302 q = makeN(z, m+1, false) | 302 q = makeN(z, m+1, false) |
303 | 303 |
304 // D1. | 304 // D1. |
305 » shift := leadingZeroBits(v[n-1]) | 305 » shift := uint(leadingZeroBits(v[n-1])) |
306 shiftLeft(v, v, shift) | 306 shiftLeft(v, v, shift) |
307 shiftLeft(u, uIn, shift) | 307 shiftLeft(u, uIn, shift) |
308 u[len(uIn)] = uIn[len(uIn)-1] >> (_W - uint(shift)) | 308 u[len(uIn)] = uIn[len(uIn)-1] >> (_W - uint(shift)) |
309 | 309 |
310 // D2. | 310 // D2. |
311 for j := m; j >= 0; j-- { | 311 for j := m; j >= 0; j-- { |
312 // D3. | 312 // D3. |
313 var qhat Word | 313 var qhat Word |
314 if u[j+n] == v[n-1] { | 314 if u[j+n] == v[n-1] { |
315 qhat = _B - 1 | 315 qhat = _B - 1 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 case 64: | 523 case 64: |
524 return int(deBruijn64Lookup[((x&-x)*(deBruijn64&_M))>>58]) | 524 return int(deBruijn64Lookup[((x&-x)*(deBruijn64&_M))>>58]) |
525 default: | 525 default: |
526 panic("Unknown word size") | 526 panic("Unknown word size") |
527 } | 527 } |
528 | 528 |
529 return 0 | 529 return 0 |
530 } | 530 } |
531 | 531 |
532 | 532 |
533 func shiftLeft(dst, src []Word, n int) { | 533 // To avoid losing the top n bits, dst should be sized so that |
| 534 // len(dst) == len(src) + 1. |
| 535 func shiftLeft(dst, src []Word, n uint) { |
534 if len(src) == 0 { | 536 if len(src) == 0 { |
535 return | 537 return |
536 } | 538 } |
537 | 539 |
538 » ñ := _W - uint(n) | 540 » ñ := _W - n |
| 541 » if len(dst) > len(src) { |
| 542 » » dst[len(src)] |= src[len(src)-1] >> ñ |
| 543 » } |
539 for i := len(src) - 1; i >= 1; i-- { | 544 for i := len(src) - 1; i >= 1; i-- { |
540 » » dst[i] = src[i] << uint(n) | 545 » » dst[i] = src[i]<<n | src[i-1]>>ñ |
541 » » dst[i] |= src[i-1] >> ñ | |
542 } | 546 } |
543 » dst[0] = src[0] << uint(n) | 547 » dst[0] = src[0] << n |
544 } | 548 } |
545 | 549 |
546 | 550 |
547 func shiftRight(dst, src []Word, n int) { | 551 func shiftRight(dst, src []Word, n uint) { |
548 if len(src) == 0 { | 552 if len(src) == 0 { |
549 return | 553 return |
550 } | 554 } |
551 | 555 |
552 » ñ := _W - uint(n) | 556 » ñ := _W - n |
553 for i := 0; i < len(src)-1; i++ { | 557 for i := 0; i < len(src)-1; i++ { |
554 » » dst[i] = src[i] >> uint(n) | 558 » » dst[i] = src[i]>>n | src[i+1]<<ñ |
555 » » dst[i] |= src[i+1] << ñ | |
556 } | 559 } |
557 » dst[len(src)-1] = src[len(src)-1] >> uint(n) | 560 » dst[len(src)-1] = src[len(src)-1] >> n |
558 } | 561 } |
559 | 562 |
560 | 563 |
561 // greaterThan returns true iff (x1<<_W + x2) > (y1<<_W + y2) | 564 // greaterThan returns true iff (x1<<_W + x2) > (y1<<_W + y2) |
562 func greaterThan(x1, x2, y1, y2 Word) bool { return x1 > y1 || x1 == y1 && x2 >
y2 } | 565 func greaterThan(x1, x2, y1, y2 Word) bool { return x1 > y1 || x1 == y1 && x2 >
y2 } |
563 | 566 |
564 | 567 |
565 // modNW returns x % d. | 568 // modNW returns x % d. |
566 func modNW(x []Word, d Word) (r Word) { | 569 func modNW(x []Word, d Word) (r Word) { |
567 // TODO(agl): we don't actually need to store the q value. | 570 // TODO(agl): we don't actually need to store the q value. |
(...skipping 10 matching lines...) Expand all Loading... |
578 | 581 |
579 zeroWords := 0 | 582 zeroWords := 0 |
580 for n[zeroWords] == 0 { | 583 for n[zeroWords] == 0 { |
581 zeroWords++ | 584 zeroWords++ |
582 } | 585 } |
583 // One of the words must be non-zero by invariant, therefore | 586 // One of the words must be non-zero by invariant, therefore |
584 // zeroWords < len(n). | 587 // zeroWords < len(n). |
585 x := trailingZeroBits(n[zeroWords]) | 588 x := trailingZeroBits(n[zeroWords]) |
586 | 589 |
587 q = makeN(nil, len(n)-zeroWords, false) | 590 q = makeN(nil, len(n)-zeroWords, false) |
588 » shiftRight(q, n[zeroWords:], x) | 591 » shiftRight(q, n[zeroWords:], uint(x)) |
589 q = normN(q) | 592 q = normN(q) |
590 | 593 |
591 k = Word(_W*zeroWords + x) | 594 k = Word(_W*zeroWords + x) |
592 return | 595 return |
593 } | 596 } |
594 | 597 |
595 | 598 |
596 // randomN creates a random integer in [0..limit), using the space in z if | 599 // randomN creates a random integer in [0..limit), using the space in z if |
597 // possible. n is the bit length of limit. | 600 // possible. n is the bit length of limit. |
598 func randomN(z []Word, rand *rand.Rand, limit []Word, n int) []Word { | 601 func randomN(z []Word, rand *rand.Rand, limit []Word, n int) []Word { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 } | 782 } |
780 if cmpNN(y, bigOne) == 0 { | 783 if cmpNN(y, bigOne) == 0 { |
781 return false | 784 return false |
782 } | 785 } |
783 } | 786 } |
784 return false | 787 return false |
785 } | 788 } |
786 | 789 |
787 return true | 790 return true |
788 } | 791 } |
OLD | NEW |