Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1608)

Side by Side Diff: src/pkg/big/nat.go

Issue 881050: code review 881050: big: Add Lsh and Value; convert pidigits to use big (Closed)
Patch Set: code review 881050: big: Add Lsh and Value; convert pidigits to use big Created 14 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/big/int_test.go ('k') | src/pkg/big/nat_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/pkg/big/int_test.go ('k') | src/pkg/big/nat_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b