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

Unified Diff: lib/src/int64.dart

Issue 1834783004: Merge in changes from SDK branch (Closed) Base URL: https://github.com/dart-lang/fixnum@master
Patch Set: Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/int32.dart ('k') | lib/src/intx.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/int64.dart
diff --git a/lib/src/int64.dart b/lib/src/int64.dart
index 641bf71e139600fe39a0057d09f33b93c5ad1e7b..2ff48229a97845f13998a6a04c8d0a99e76af582 100644
--- a/lib/src/int64.dart
+++ b/lib/src/int64.dart
@@ -30,7 +30,7 @@ class Int64 implements IntX {
static const int _MASK = 4194303; // (1 << _BITS) - 1
static const int _MASK2 = 1048575; // (1 << _BITS2) - 1
static const int _SIGN_BIT = 19; // _BITS2 - 1
- static const int _SIGN_BIT_MASK = 524288; // 1 << _SIGN_BIT
+ static const int _SIGN_BIT_MASK = 1 << _SIGN_BIT;
/**
* The maximum positive value attainable by an [Int64], namely
@@ -70,10 +70,7 @@ class Int64 implements IntX {
* [Int64].
*/
static Int64 parseRadix(String s, int radix) {
- if ((radix <= 1) || (radix > 36)) {
- throw new ArgumentError("Bad radix: $radix");
- }
- return _parseRadix(s, radix);
+ return _parseRadix(s, Int32._validateRadix(radix));
}
static Int64 _parseRadix(String s, int radix) {
@@ -83,9 +80,7 @@ class Int64 implements IntX {
negative = true;
i++;
}
- int d0 = 0,
- d1 = 0,
- d2 = 0; // low, middle, high components.
+ int d0 = 0, d1 = 0, d2 = 0; // low, middle, high components.
for (; i < s.length; i++) {
int c = s.codeUnitAt(i);
int digit = Int32._decodeDigit(c);
@@ -109,7 +104,7 @@ class Int64 implements IntX {
if (negative) return _negate(d0, d1, d2);
- return new Int64._bits(d0, d1, d2);
+ return Int64._masked(d0, d1, d2);
}
/**
@@ -129,27 +124,20 @@ class Int64 implements IntX {
/**
* Constructs an [Int64] with a given [int] value; zero by default.
*/
- factory Int64([int value = 0]) {
- int v0 = 0,
- v1 = 0,
- v2 = 0;
+ factory Int64([int value=0]) {
+ int v0 = 0, v1 = 0, v2 = 0;
bool negative = false;
if (value < 0) {
negative = true;
value = -value - 1;
}
- if (_haveBigInts) {
- v0 = _MASK & value;
- v1 = _MASK & (value >> _BITS);
- v2 = _MASK2 & (value >> _BITS01);
- } else {
- // Avoid using bitwise operations that coerce their input to 32 bits.
- v2 = value ~/ 17592186044416; // 2^44
- value -= v2 * 17592186044416;
- v1 = value ~/ 4194304; // 2^22
- value -= v1 * 4194304;
- v0 = value;
- }
+ // Avoid using bitwise operations that in JavaScript coerce their input to
+ // 32 bits.
+ v2 = value ~/ 17592186044416; // 2^44
+ value -= v2 * 17592186044416;
+ v1 = value ~/ 4194304; // 2^22
+ value -= v1 * 4194304;
+ v0 = value;
if (negative) {
v0 = ~v0;
@@ -197,7 +185,7 @@ class Int64 implements IntX {
bottom |= bytes[7] & 0xff;
return new Int64.fromInts(top, bottom);
- }
+ }
/**
* Constructs an [Int64] from a pair of 32-bit integers having the value
@@ -206,23 +194,23 @@ class Int64 implements IntX {
factory Int64.fromInts(int top, int bottom) {
top &= 0xffffffff;
bottom &= 0xffffffff;
- int d0 = bottom & _MASK;
- int d1 = ((top & 0xfff) << 10) | ((bottom >> _BITS) & 0x3ff);
- int d2 = (top >> 12) & _MASK2;
- return new Int64._bits(d0, d1, d2);
+ int d0 = _MASK & bottom;
+ int d1 = ((0xfff & top) << 10) | (0x3ff & (bottom >> _BITS));
+ int d2 = _MASK2 & (top >> 12);
+ return Int64._masked(d0, d1, d2);
}
// Returns the [Int64] representation of the specified value. Throws
// [ArgumentError] for non-integer arguments.
- static Int64 _promote(val) {
- if (val is Int64) {
- return val;
- } else if (val is int) {
- return new Int64(val);
- } else if (val is Int32) {
- return val.toInt64();
+ static Int64 _promote(value) {
+ if (value is Int64) {
+ return value;
+ } else if (value is int) {
+ return new Int64(value);
+ } else if (value is Int32) {
+ return value.toInt64();
}
- throw new ArgumentError(val);
+ throw new ArgumentError.value(value);
}
Int64 operator +(other) {
@@ -316,12 +304,9 @@ class Int64 implements IntX {
// Propagate high bits from c0 -> c1, c1 -> c2.
c1 += c0 >> _BITS;
- c0 &= _MASK;
c2 += c1 >> _BITS;
- c1 &= _MASK;
- c2 &= _MASK2;
- return new Int64._bits(c0, c1, c2);
+ return Int64._masked(c0, c1, c2);
}
Int64 operator %(other) => _divide(this, other, _RETURN_MOD);
@@ -335,7 +320,7 @@ class Int64 implements IntX {
int a0 = _l & o._l;
int a1 = _m & o._m;
int a2 = _h & o._h;
- return new Int64._bits(a0, a1, a2);
+ return Int64._masked(a0, a1, a2);
}
Int64 operator |(other) {
@@ -343,7 +328,7 @@ class Int64 implements IntX {
int a0 = _l | o._l;
int a1 = _m | o._m;
int a2 = _h | o._h;
- return new Int64._bits(a0, a1, a2);
+ return Int64._masked(a0, a1, a2);
}
Int64 operator ^(other) {
@@ -351,7 +336,7 @@ class Int64 implements IntX {
int a0 = _l ^ o._l;
int a1 = _m ^ o._m;
int a2 = _h ^ o._h;
- return new Int64._bits(a0, a1, a2);
+ return Int64._masked(a0, a1, a2);
}
Int64 operator ~() {
@@ -360,7 +345,7 @@ class Int64 implements IntX {
Int64 operator <<(int n) {
if (n < 0) {
- throw new ArgumentError(n);
+ throw new ArgumentError.value(n);
}
n &= 63;
@@ -384,7 +369,7 @@ class Int64 implements IntX {
Int64 operator >>(int n) {
if (n < 0) {
- throw new ArgumentError(n);
+ throw new ArgumentError.value(n);
}
n &= 63;
@@ -427,7 +412,7 @@ class Int64 implements IntX {
Int64 shiftRightUnsigned(int n) {
if (n < 0) {
- throw new ArgumentError(n);
+ throw new ArgumentError.value(n);
}
n &= 63;
@@ -473,7 +458,9 @@ class Int64 implements IntX {
return false;
}
- int compareTo(Comparable other) {
+ int compareTo(Comparable other) =>_compareTo(other);
+
+ int _compareTo(other) {
Int64 o = _promote(other);
int signa = _h >> (_BITS2 - 1);
int signb = o._h >> (_BITS2 - 1);
@@ -498,21 +485,10 @@ class Int64 implements IntX {
return 0;
}
- bool operator <(other) {
- return this.compareTo(other) < 0;
- }
-
- bool operator <=(other) {
- return this.compareTo(other) <= 0;
- }
-
- bool operator >(other) {
- return this.compareTo(other) > 0;
- }
-
- bool operator >=(other) {
- return this.compareTo(other) >= 0;
- }
+ bool operator <(other) => _compareTo(other) < 0;
+ bool operator <=(other) => _compareTo(other) <= 0;
+ bool operator >(other) => this._compareTo(other) > 0;
+ bool operator >=(other) => _compareTo(other) >= 0;
bool get isEven => (_l & 0x1) == 0;
bool get isMaxValue => (_h == _MASK2 >> 1) && _m == _MASK && _l == _MASK;
@@ -523,9 +499,7 @@ class Int64 implements IntX {
int get bitLength {
if (isZero) return 0;
- int a0 = _l,
- a1 = _m,
- a2 = _h;
+ int a0 = _l, a1 = _m, a2 = _h;
if (isNegative) {
a0 = _MASK & ~a0;
a1 = _MASK & ~a1;
@@ -601,24 +575,24 @@ class Int64 implements IntX {
}
Int64 toSigned(int width) {
- if (width < 1 || width > 64) throw new ArgumentError(width);
+ if (width < 1 || width > 64) throw new RangeError.range(width, 1, 64);
if (width > _BITS01) {
return Int64._masked(_l, _m, _h.toSigned(width - _BITS01));
} else if (width > _BITS) {
int m = _m.toSigned(width - _BITS);
return m.isNegative
? Int64._masked(_l, m, _MASK2)
- : Int64._masked(_l, m, 0); // Masking for type inferrer.
+ : Int64._masked(_l, m, 0); // Masking for type inferrer.
} else {
int l = _l.toSigned(width);
return l.isNegative
? Int64._masked(l, _MASK, _MASK2)
- : Int64._masked(l, 0, 0); // Masking for type inferrer.
+ : Int64._masked(l, 0, 0); // Masking for type inferrer.
}
}
Int64 toUnsigned(int width) {
- if (width < 0 || width > 64) throw new ArgumentError(width);
+ if (width < 0 || width > 64) throw new RangeError.range(width, 0, 64);
if (width > _BITS01) {
int h = _h.toUnsigned(width - _BITS01);
return Int64._masked(_l, _m, h);
@@ -650,23 +624,15 @@ class Int64 implements IntX {
int l = _l;
int m = _m;
int h = _h;
- bool negative = false;
+ // In the sum we add least significant to most significant so that in
+ // JavaScript double arithmetic rounding occurs on only the last addition.
if ((_h & _SIGN_BIT_MASK) != 0) {
l = _MASK & ~_l;
m = _MASK & ~_m;
h = _MASK2 & ~_h;
- negative = true;
- }
-
- if (_haveBigInts) {
- int result = (h << _BITS01) | (m << _BITS) | l;
- return negative ? -result - 1 : result;
+ return -((1 + l) + (4194304 * m) + (17592186044416 * h));
} else {
- if (negative) {
- return -((l + 1) + (m * 4194304) + (h * 17592186044416));
- } else {
- return (l + (m * 4194304)) + (h * 17592186044416);
- }
+ return l + (4194304 * m) + (17592186044416 * h);
}
}
@@ -692,7 +658,6 @@ class Int64 implements IntX {
if (isZero) return "0";
Int64 x = this;
String hexStr = "";
- Int64 digit_f = new Int64(0xf);
while (!x.isZero) {
int digit = x._l & 0xf;
hexStr = "${_hexDigit(digit)}$hexStr";
@@ -702,10 +667,7 @@ class Int64 implements IntX {
}
String toRadixString(int radix) {
- if ((radix <= 1) || (radix > 36)) {
- throw new ArgumentError("Bad radix: $radix");
- }
- return _toRadixString(radix);
+ return _toRadixString(Int32._validateRadix(radix));
}
String _toRadixString(int radix) {
@@ -764,9 +726,7 @@ class Int64 implements IntX {
// need only two chunks, but radix values 17-19 and 33-36 generate only 15
// or 16 bits per iteration, so sometimes the third chunk is needed.
- String chunk1 = "",
- chunk2 = "",
- chunk3 = "";
+ String chunk1 = "", chunk2 = "", chunk3 = "";
while (!(d4 == 0 && d3 == 0)) {
int q = d4 ~/ fatRadix;
@@ -867,24 +827,6 @@ class Int64 implements IntX {
return _sub(0, 0, 0, b0, b1, b2);
}
- // Determine whether the platform supports ints greater than 2^53
- // without loss of precision.
- static bool _haveBigIntsCached = null;
-
- static bool get _haveBigInts {
- if (_haveBigIntsCached == null) {
- var x = 9007199254740992;
- // Defeat compile-time constant folding.
- if (2 + 2 != 4) {
- x = 0;
- }
- var y = x + 1;
- var same = y == x;
- _haveBigIntsCached = !same;
- }
- return _haveBigIntsCached;
- }
-
String _hexDigit(int digit) => "0123456789ABCDEF"[digit];
// Work around dart2js bugs with negative arguments to '>>' operator.
@@ -930,15 +872,11 @@ class Int64 implements IntX {
static _divideHelper(
// up to 64 bits unsigned in a2/a1/a0 and b2/b1/b0
- int a0, int a1, int a2, bool aNeg, // input A.
- int b0, int b1, int b2, bool bNeg, // input B.
+ int a0, int a1, int a2, bool aNeg, // input A.
+ int b0, int b1, int b2, bool bNeg, // input B.
int what) {
- int q0 = 0,
- q1 = 0,
- q2 = 0; // result Q.
- int r0 = 0,
- r1 = 0,
- r2 = 0; // result R.
+ int q0 = 0, q1 = 0, q2 = 0; // result Q.
+ int r0 = 0, r1 = 0, r2 = 0; // result R.
if (b2 == 0 && b1 == 0 && b0 < (1 << (30 - _BITS))) {
// Small divisor can be handled by single-digit division within Smi range.
@@ -986,7 +924,7 @@ class Int64 implements IntX {
q0 = q0d.toInt();
assert(q0 + K1 * q1 + K2 * q2 == (ad / bd).floorToDouble());
- assert(q2 == 0 || b2 == 0); // Q and B can't both be big since Q*B <= A.
+ assert(q2 == 0 || b2 == 0); // Q and B can't both be big since Q*B <= A.
// P = Q * B, using doubles to hold intermediates.
// We don't need all partial sums since Q*B <= A.
@@ -997,7 +935,7 @@ class Int64 implements IntX {
double p1carry = (p1d / K1).floorToDouble();
p1d = p1d - p1carry * K1;
double p2d = q2d * b0 + q1d * b1 + q0d * b2 + p1carry;
- assert(p2d <= _MASK2); // No partial sum overflow.
+ assert(p2d <= _MASK2); // No partial sum overflow.
// R = A - P
int diff0 = a0 - p0d.toInt();
@@ -1009,7 +947,8 @@ class Int64 implements IntX {
// while (R < 0 || R >= B)
// adjust R towards [0, B)
- while (r2 >= _SIGN_BIT_MASK ||
+ while (
+ r2 >= _SIGN_BIT_MASK ||
r2 > b2 ||
(r2 == b2 && (r1 > b1 || (r1 == b1 && r0 >= b0)))) {
// Direction multiplier for adjustment.
@@ -1034,17 +973,17 @@ class Int64 implements IntX {
// 0 <= R < B
assert(Int64.ZERO <= new Int64._bits(r0, r1, r2));
- assert(r2 < b2 || // Handles case where B = -(MIN_VALUE)
+ assert(r2 < b2 || // Handles case where B = -(MIN_VALUE)
new Int64._bits(r0, r1, r2) < new Int64._bits(b0, b1, b2));
assert(what == _RETURN_DIV || what == _RETURN_MOD || what == _RETURN_REM);
if (what == _RETURN_DIV) {
if (aNeg != bNeg) return _negate(q0, q1, q2);
- return Int64._masked(q0, q1, q2); // Masking for type inferrer.
+ return Int64._masked(q0, q1, q2); // Masking for type inferrer.
}
if (!aNeg) {
- return new Int64._bits(_MASK & r0, r1, r2); // Masking for type inferrer.
+ return Int64._masked(r0, r1, r2); // Masking for type inferrer.
}
if (what == _RETURN_MOD) {
« no previous file with comments | « lib/src/int32.dart ('k') | lib/src/intx.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698