Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: pkg/fixnum/lib/src/int64.dart

Issue 24388004: Added bitLength, clamp(), toDouble(), toSigned(), toUnsigned(). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use string literals in place of doubles where precision is exceeded Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/fixnum/lib/src/int32.dart ('k') | pkg/fixnum/lib/src/intx.dart » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of fixnum; 5 part of fixnum;
6 6
7 /** 7 /**
8 * An immutable 64-bit signed integer, in the range [-2^63, 2^63 - 1]. 8 * An immutable 64-bit signed integer, in the range [-2^63, 2^63 - 1].
9 * Arithmetic operations may overflow in order to maintain this range. 9 * Arithmetic operations may overflow in order to maintain this range.
10 */ 10 */
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 return this.compareTo(other) >= 0; 509 return this.compareTo(other) >= 0;
510 } 510 }
511 511
512 bool get isEven => (_l & 0x1) == 0; 512 bool get isEven => (_l & 0x1) == 0;
513 bool get isMaxValue => (_h == _MASK2 >> 1) && _m == _MASK && _l == _MASK; 513 bool get isMaxValue => (_h == _MASK2 >> 1) && _m == _MASK && _l == _MASK;
514 bool get isMinValue => _h == _SIGN_BIT_MASK && _m == 0 && _l == 0; 514 bool get isMinValue => _h == _SIGN_BIT_MASK && _m == 0 && _l == 0;
515 bool get isNegative => (_h & _SIGN_BIT_MASK) != 0; 515 bool get isNegative => (_h & _SIGN_BIT_MASK) != 0;
516 bool get isOdd => (_l & 0x1) == 1; 516 bool get isOdd => (_l & 0x1) == 1;
517 bool get isZero => _h == 0 && _m == 0 && _l == 0; 517 bool get isZero => _h == 0 && _m == 0 && _l == 0;
518 518
519 int get bitLength {
520 if (isZero) return 0;
521 int a0 = _l, a1 = _m, a2 = _h;
522 if (isNegative) {
523 a0 = _MASK & ~a0;
524 a1 = _MASK & ~a1;
525 a2 = _MASK2 & ~a2;
526 }
527 if (a2 != 0) return _BITS01 + a2.bitLength;
528 if (a1 != 0) return _BITS + a1.bitLength;
529 return a0.bitLength;
530 }
531
519 /** 532 /**
520 * Returns a hash code based on all the bits of this [Int64]. 533 * Returns a hash code based on all the bits of this [Int64].
521 */ 534 */
522 int get hashCode { 535 int get hashCode {
523 // TODO(sra): Should we ensure that hashCode values match corresponding int? 536 // TODO(sra): Should we ensure that hashCode values match corresponding int?
524 // i.e. should `new Int64(x).hashCode == x.hashCode`? 537 // i.e. should `new Int64(x).hashCode == x.hashCode`?
525 int bottom = ((_m & 0x3ff) << _BITS) | _l; 538 int bottom = ((_m & 0x3ff) << _BITS) | _l;
526 int top = (_h << 12) | ((_m >> 10) & 0xfff); 539 int top = (_h << 12) | ((_m >> 10) & 0xfff);
527 return bottom ^ top; 540 return bottom ^ top;
528 } 541 }
529 542
530 Int64 abs() { 543 Int64 abs() {
531 return this.isNegative ? -this : this; 544 return this.isNegative ? -this : this;
532 } 545 }
533 546
547 Int64 clamp(lowerLimit, upperLimit) {
548 Int64 lower = _promote(lowerLimit);
549 Int64 upper = _promote(upperLimit);
550 if (this < lower) return lower;
551 if (this > upper) return upper;
552 return this;
553 }
554
534 /** 555 /**
535 * Returns the number of leading zeros in this [Int64] as an [int] 556 * Returns the number of leading zeros in this [Int64] as an [int]
536 * between 0 and 64. 557 * between 0 and 64.
537 */ 558 */
538 int numberOfLeadingZeros() { 559 int numberOfLeadingZeros() {
539 int b2 = Int32._numberOfLeadingZeros(_h); 560 int b2 = Int32._numberOfLeadingZeros(_h);
540 if (b2 == 32) { 561 if (b2 == 32) {
541 int b1 = Int32._numberOfLeadingZeros(_m); 562 int b1 = Int32._numberOfLeadingZeros(_m);
542 if (b1 == 32) { 563 if (b1 == 32) {
543 return Int32._numberOfLeadingZeros(_l) + 32; 564 return Int32._numberOfLeadingZeros(_l) + 32;
(...skipping 21 matching lines...) Expand all
565 } 586 }
566 587
567 zeros = Int32._numberOfTrailingZeros(_h); 588 zeros = Int32._numberOfTrailingZeros(_h);
568 if (zeros < 32) { 589 if (zeros < 32) {
569 return _BITS01 + zeros; 590 return _BITS01 + zeros;
570 } 591 }
571 // All zeros 592 // All zeros
572 return 64; 593 return 64;
573 } 594 }
574 595
596 Int64 toSigned(int width) {
597 if (width < 1 || width > 64) throw new ArgumentError(width);
598 if (width > _BITS01) {
599 return Int64._masked(_l, _m, _h.toSigned(width - _BITS01));
600 } else if (width > _BITS) {
601 int m = _m.toSigned(width - _BITS);
602 return m.isNegative ? Int64._masked(_l, m, _MASK2) :
603 new Int64._bits(_l, m, 0);
604 } else {
605 int l = _l.toSigned(width);
606 return l.isNegative ? Int64._masked(l, _MASK, _MASK2) :
607 new Int64._bits(l, 0, 0);
608 }
609 }
610
611 Int64 toUnsigned(int width) {
612 if (width < 0 || width > 64) throw new ArgumentError(width);
613 if (width > _BITS01) {
614 int h = _h.toUnsigned(width - _BITS01);
615 return Int64._masked(_l, _m, h);
616 } else if (width > _BITS) {
617 int m = _m.toUnsigned(width - _BITS);
618 return Int64._masked(_l, m, 0);
619 } else {
620 int l = _l.toUnsigned(width);
621 return Int64._masked(l, 0, 0);
622 }
623 }
624
575 List<int> toBytes() { 625 List<int> toBytes() {
576 List<int> result = new List<int>(8); 626 List<int> result = new List<int>(8);
577 result[0] = _l & 0xff; 627 result[0] = _l & 0xff;
578 result[1] = (_l >> 8) & 0xff; 628 result[1] = (_l >> 8) & 0xff;
579 result[2] = ((_m << 6) & 0xfc) | ((_l >> 16) & 0x3f); 629 result[2] = ((_m << 6) & 0xfc) | ((_l >> 16) & 0x3f);
580 result[3] = (_m >> 2) & 0xff; 630 result[3] = (_m >> 2) & 0xff;
581 result[4] = (_m >> 10) & 0xff; 631 result[4] = (_m >> 10) & 0xff;
582 result[5] = ((_h << 4) & 0xf0) | ((_m >> 18) & 0xf); 632 result[5] = ((_h << 4) & 0xf0) | ((_m >> 18) & 0xf);
583 result[6] = (_h >> 4) & 0xff; 633 result[6] = (_h >> 4) & 0xff;
584 result[7] = (_h >> 12) & 0xff; 634 result[7] = (_h >> 12) & 0xff;
585 return result; 635 return result;
586 } 636 }
587 637
638 double toDouble() => toInt().toDouble();
639
588 int toInt() { 640 int toInt() {
589 int l = _l; 641 int l = _l;
590 int m = _m; 642 int m = _m;
591 int h = _h; 643 int h = _h;
592 bool negative = false; 644 bool negative = false;
593 if ((_h & _SIGN_BIT_MASK) != 0) { 645 if ((_h & _SIGN_BIT_MASK) != 0) {
594 l = ~_l & _MASK; 646 l = _MASK & ~_l;
595 m = ~_m & _MASK; 647 m = _MASK & ~_m;
596 h = ~_h & _MASK2; 648 h = _MASK2 & ~_h;
597 negative = true; 649 negative = true;
598 } 650 }
599 651
600 int result;
601 if (_haveBigInts) { 652 if (_haveBigInts) {
602 result = (h << _BITS01) | (m << _BITS) | l; 653 int result = (h << _BITS01) | (m << _BITS) | l;
654 return negative ? -result - 1 : result;
603 } else { 655 } else {
604 result = (h * 17592186044416) + (m * 4194304) + l; 656 if (negative) {
657 return -((l + 1) + (m * 4194304) + (h * 17592186044416));
658 } else {
659 return (l + (m * 4194304)) + (h * 17592186044416);
660 }
605 } 661 }
606 return negative ? -result - 1 : result;
607 } 662 }
608 663
609 /** 664 /**
610 * Returns an [Int32] containing the low 32 bits of this [Int64]. 665 * Returns an [Int32] containing the low 32 bits of this [Int64].
611 */ 666 */
612 Int32 toInt32() { 667 Int32 toInt32() {
613 return new Int32(((_m & 0x3ff) << _BITS) | _l); 668 return new Int32(((_m & 0x3ff) << _BITS) | _l);
614 } 669 }
615 670
616 /** 671 /**
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 if (r0 == 0 && r1 == 0 && r2 == 0) { 1039 if (r0 == 0 && r1 == 0 && r2 == 0) {
985 return ZERO; 1040 return ZERO;
986 } else { 1041 } else {
987 return _sub(b0, b1, b2, r0, r1, r2); 1042 return _sub(b0, b1, b2, r0, r1, r2);
988 } 1043 }
989 } else { 1044 } else {
990 return _negate(r0, r1, r2); 1045 return _negate(r0, r1, r2);
991 } 1046 }
992 } 1047 }
993 } 1048 }
OLDNEW
« no previous file with comments | « pkg/fixnum/lib/src/int32.dart ('k') | pkg/fixnum/lib/src/intx.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698