LEFT | RIGHT |
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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 // To avoid losing the top n bits, dst should be sized so that | 533 // To avoid losing the top n bits, dst should be sized so that |
534 // len(dst) == len(src) + 1. | 534 // len(dst) == len(src) + 1. |
535 func shiftLeft(dst, src []Word, n int) { | 535 func shiftLeft(dst, src []Word, n uint) { |
536 if len(src) == 0 { | 536 if len(src) == 0 { |
537 return | 537 return |
538 } | 538 } |
539 | 539 |
540 » ñ := _W - uint(n) | 540 » ñ := _W - n |
541 » dst[len(dst)-1] |= src[len(src)-1] >> ñ | 541 » if len(dst) > len(src) { |
| 542 » » dst[len(src)] |= src[len(src)-1] >> ñ |
| 543 » } |
542 for i := len(src) - 1; i >= 1; i-- { | 544 for i := len(src) - 1; i >= 1; i-- { |
543 » » dst[i] = src[i] << uint(n) | 545 » » dst[i] = src[i]<<n | src[i-1]>>ñ |
544 » » dst[i] |= src[i-1] >> ñ | 546 » } |
545 » } | 547 » dst[0] = src[0] << n |
546 » dst[0] = src[0] << uint(n) | 548 } |
547 } | 549 |
548 | 550 |
549 | 551 func shiftRight(dst, src []Word, n uint) { |
550 func shiftRight(dst, src []Word, n int) { | |
551 if len(src) == 0 { | 552 if len(src) == 0 { |
552 return | 553 return |
553 } | 554 } |
554 | 555 |
555 » ñ := _W - uint(n) | 556 » ñ := _W - n |
556 for i := 0; i < len(src)-1; i++ { | 557 for i := 0; i < len(src)-1; i++ { |
557 » » dst[i] = src[i] >> uint(n) | 558 » » dst[i] = src[i]>>n | src[i+1]<<ñ |
558 » » dst[i] |= src[i+1] << ñ | 559 » } |
559 » } | 560 » dst[len(src)-1] = src[len(src)-1] >> n |
560 » dst[len(src)-1] = src[len(src)-1] >> uint(n) | |
561 } | 561 } |
562 | 562 |
563 | 563 |
564 // greaterThan returns true iff (x1<<_W + x2) > (y1<<_W + y2) | 564 // greaterThan returns true iff (x1<<_W + x2) > (y1<<_W + y2) |
565 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 } |
566 | 566 |
567 | 567 |
568 // modNW returns x % d. | 568 // modNW returns x % d. |
569 func modNW(x []Word, d Word) (r Word) { | 569 func modNW(x []Word, d Word) (r Word) { |
570 // 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... |
581 | 581 |
582 zeroWords := 0 | 582 zeroWords := 0 |
583 for n[zeroWords] == 0 { | 583 for n[zeroWords] == 0 { |
584 zeroWords++ | 584 zeroWords++ |
585 } | 585 } |
586 // One of the words must be non-zero by invariant, therefore | 586 // One of the words must be non-zero by invariant, therefore |
587 // zeroWords < len(n). | 587 // zeroWords < len(n). |
588 x := trailingZeroBits(n[zeroWords]) | 588 x := trailingZeroBits(n[zeroWords]) |
589 | 589 |
590 q = makeN(nil, len(n)-zeroWords, false) | 590 q = makeN(nil, len(n)-zeroWords, false) |
591 » shiftRight(q, n[zeroWords:], x) | 591 » shiftRight(q, n[zeroWords:], uint(x)) |
592 q = normN(q) | 592 q = normN(q) |
593 | 593 |
594 k = Word(_W*zeroWords + x) | 594 k = Word(_W*zeroWords + x) |
595 return | 595 return |
596 } | 596 } |
597 | 597 |
598 | 598 |
599 // 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 |
600 // possible. n is the bit length of limit. | 600 // possible. n is the bit length of limit. |
601 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... |
782 } | 782 } |
783 if cmpNN(y, bigOne) == 0 { | 783 if cmpNN(y, bigOne) == 0 { |
784 return false | 784 return false |
785 } | 785 } |
786 } | 786 } |
787 return false | 787 return false |
788 } | 788 } |
789 | 789 |
790 return true | 790 return true |
791 } | 791 } |
LEFT | RIGHT |