| OLD | NEW |
| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 * Constructs an [Int64] with a given bitwise representation. No validation | 63 * Constructs an [Int64] with a given bitwise representation. No validation |
| 64 * is performed. | 64 * is performed. |
| 65 */ | 65 */ |
| 66 const Int64._bits(int this._l, int this._m, int this._h); | 66 const Int64._bits(int this._l, int this._m, int this._h); |
| 67 | 67 |
| 68 /** | 68 /** |
| 69 * Parses a [String] in a given [radix] between 2 and 36 and returns an | 69 * Parses a [String] in a given [radix] between 2 and 36 and returns an |
| 70 * [Int64]. | 70 * [Int64]. |
| 71 */ | 71 */ |
| 72 static Int64 parseRadix(String s, int radix) { | 72 static Int64 parseRadix(String s, int radix) { |
| 73 if ((radix <= 1) || (radix > 36)) { | 73 return _parseRadix(s, Int32._validateRadix(radix)); |
| 74 throw new ArgumentError("Bad radix: $radix"); | |
| 75 } | |
| 76 return _parseRadix(s, radix); | |
| 77 } | 74 } |
| 78 | 75 |
| 79 static Int64 _parseRadix(String s, int radix) { | 76 static Int64 _parseRadix(String s, int radix) { |
| 80 int i = 0; | 77 int i = 0; |
| 81 bool negative = false; | 78 bool negative = false; |
| 82 if (s[0] == '-') { | 79 if (s[0] == '-') { |
| 83 negative = true; | 80 negative = true; |
| 84 i++; | 81 i++; |
| 85 } | 82 } |
| 86 int d0 = 0, d1 = 0, d2 = 0; // low, middle, high components. | 83 int d0 = 0, d1 = 0, d2 = 0; // low, middle, high components. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 top &= 0xffffffff; | 200 top &= 0xffffffff; |
| 204 bottom &= 0xffffffff; | 201 bottom &= 0xffffffff; |
| 205 int d0 = _MASK & bottom; | 202 int d0 = _MASK & bottom; |
| 206 int d1 = ((0xfff & top) << 10) | (0x3ff & (bottom >> _BITS)); | 203 int d1 = ((0xfff & top) << 10) | (0x3ff & (bottom >> _BITS)); |
| 207 int d2 = _MASK2 & (top >> 12); | 204 int d2 = _MASK2 & (top >> 12); |
| 208 return new Int64._bits(d0, d1, d2); | 205 return new Int64._bits(d0, d1, d2); |
| 209 } | 206 } |
| 210 | 207 |
| 211 // Returns the [Int64] representation of the specified value. Throws | 208 // Returns the [Int64] representation of the specified value. Throws |
| 212 // [ArgumentError] for non-integer arguments. | 209 // [ArgumentError] for non-integer arguments. |
| 213 static Int64 _promote(val) { | 210 static Int64 _promote(value) { |
| 214 if (val is Int64) { | 211 if (value is Int64) { |
| 215 return val; | 212 return value; |
| 216 } else if (val is int) { | 213 } else if (value is int) { |
| 217 return new Int64(val); | 214 return new Int64(value); |
| 218 } else if (val is Int32) { | 215 } else if (value is Int32) { |
| 219 return val.toInt64(); | 216 return value.toInt64(); |
| 220 } | 217 } |
| 221 throw new ArgumentError(val); | 218 throw new ArgumentError.value(value); |
| 222 } | 219 } |
| 223 | 220 |
| 224 Int64 operator +(other) { | 221 Int64 operator +(other) { |
| 225 Int64 o = _promote(other); | 222 Int64 o = _promote(other); |
| 226 int sum0 = _l + o._l; | 223 int sum0 = _l + o._l; |
| 227 int sum1 = _m + o._m + (sum0 >> _BITS); | 224 int sum1 = _m + o._m + (sum0 >> _BITS); |
| 228 int sum2 = _h + o._h + (sum1 >> _BITS); | 225 int sum2 = _h + o._h + (sum1 >> _BITS); |
| 229 return Int64._masked(sum0, sum1, sum2); | 226 return Int64._masked(sum0, sum1, sum2); |
| 230 } | 227 } |
| 231 | 228 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 int a2 = _h ^ o._h; | 343 int a2 = _h ^ o._h; |
| 347 return Int64._masked(a0, a1, a2); | 344 return Int64._masked(a0, a1, a2); |
| 348 } | 345 } |
| 349 | 346 |
| 350 Int64 operator ~() { | 347 Int64 operator ~() { |
| 351 return Int64._masked(~_l, ~_m, ~_h); | 348 return Int64._masked(~_l, ~_m, ~_h); |
| 352 } | 349 } |
| 353 | 350 |
| 354 Int64 operator <<(int n) { | 351 Int64 operator <<(int n) { |
| 355 if (n < 0) { | 352 if (n < 0) { |
| 356 throw new ArgumentError(n); | 353 throw new ArgumentError.value(n); |
| 357 } | 354 } |
| 358 n &= 63; | 355 n &= 63; |
| 359 | 356 |
| 360 int res0, res1, res2; | 357 int res0, res1, res2; |
| 361 if (n < _BITS) { | 358 if (n < _BITS) { |
| 362 res0 = _l << n; | 359 res0 = _l << n; |
| 363 res1 = (_m << n) | (_l >> (_BITS - n)); | 360 res1 = (_m << n) | (_l >> (_BITS - n)); |
| 364 res2 = (_h << n) | (_m >> (_BITS - n)); | 361 res2 = (_h << n) | (_m >> (_BITS - n)); |
| 365 } else if (n < _BITS01) { | 362 } else if (n < _BITS01) { |
| 366 res0 = 0; | 363 res0 = 0; |
| 367 res1 = _l << (n - _BITS); | 364 res1 = _l << (n - _BITS); |
| 368 res2 = (_m << (n - _BITS)) | (_l >> (_BITS01 - n)); | 365 res2 = (_m << (n - _BITS)) | (_l >> (_BITS01 - n)); |
| 369 } else { | 366 } else { |
| 370 res0 = 0; | 367 res0 = 0; |
| 371 res1 = 0; | 368 res1 = 0; |
| 372 res2 = _l << (n - _BITS01); | 369 res2 = _l << (n - _BITS01); |
| 373 } | 370 } |
| 374 | 371 |
| 375 return Int64._masked(res0, res1, res2); | 372 return Int64._masked(res0, res1, res2); |
| 376 } | 373 } |
| 377 | 374 |
| 378 Int64 operator >>(int n) { | 375 Int64 operator >>(int n) { |
| 379 if (n < 0) { | 376 if (n < 0) { |
| 380 throw new ArgumentError(n); | 377 throw new ArgumentError.value(n); |
| 381 } | 378 } |
| 382 n &= 63; | 379 n &= 63; |
| 383 | 380 |
| 384 int res0, res1, res2; | 381 int res0, res1, res2; |
| 385 | 382 |
| 386 // Sign extend h(a). | 383 // Sign extend h(a). |
| 387 int a2 = _h; | 384 int a2 = _h; |
| 388 bool negative = (a2 & _SIGN_BIT_MASK) != 0; | 385 bool negative = (a2 & _SIGN_BIT_MASK) != 0; |
| 389 if (negative && _MASK > _MASK2) { | 386 if (negative && _MASK > _MASK2) { |
| 390 // Add extra one bits on the left so the sign gets shifted into the wider | 387 // Add extra one bits on the left so the sign gets shifted into the wider |
| (...skipping 22 matching lines...) Expand all Loading... |
| 413 if (negative) { | 410 if (negative) { |
| 414 res0 |= _MASK & ~(_MASK >> (n - _BITS01)); | 411 res0 |= _MASK & ~(_MASK >> (n - _BITS01)); |
| 415 } | 412 } |
| 416 } | 413 } |
| 417 | 414 |
| 418 return Int64._masked(res0, res1, res2); | 415 return Int64._masked(res0, res1, res2); |
| 419 } | 416 } |
| 420 | 417 |
| 421 Int64 shiftRightUnsigned(int n) { | 418 Int64 shiftRightUnsigned(int n) { |
| 422 if (n < 0) { | 419 if (n < 0) { |
| 423 throw new ArgumentError(n); | 420 throw new ArgumentError.value(n); |
| 424 } | 421 } |
| 425 n &= 63; | 422 n &= 63; |
| 426 | 423 |
| 427 int res0, res1, res2; | 424 int res0, res1, res2; |
| 428 int a2 = _MASK2 & _h; // Ensure a2 is positive. | 425 int a2 = _MASK2 & _h; // Ensure a2 is positive. |
| 429 if (n < _BITS) { | 426 if (n < _BITS) { |
| 430 res2 = a2 >> n; | 427 res2 = a2 >> n; |
| 431 res1 = (_m >> n) | (a2 << (_BITS - n)); | 428 res1 = (_m >> n) | (a2 << (_BITS - n)); |
| 432 res0 = (_l >> n) | (_m << (_BITS - n)); | 429 res0 = (_l >> n) | (_m << (_BITS - n)); |
| 433 } else if (n < _BITS01) { | 430 } else if (n < _BITS01) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 | 573 |
| 577 zeros = Int32._numberOfTrailingZeros(_h); | 574 zeros = Int32._numberOfTrailingZeros(_h); |
| 578 if (zeros < 32) { | 575 if (zeros < 32) { |
| 579 return _BITS01 + zeros; | 576 return _BITS01 + zeros; |
| 580 } | 577 } |
| 581 // All zeros | 578 // All zeros |
| 582 return 64; | 579 return 64; |
| 583 } | 580 } |
| 584 | 581 |
| 585 Int64 toSigned(int width) { | 582 Int64 toSigned(int width) { |
| 586 if (width < 1 || width > 64) throw new ArgumentError(width); | 583 if (width < 1 || width > 64) throw new RangeError.range(width, 1, 64); |
| 587 if (width > _BITS01) { | 584 if (width > _BITS01) { |
| 588 return Int64._masked(_l, _m, _h.toSigned(width - _BITS01)); | 585 return Int64._masked(_l, _m, _h.toSigned(width - _BITS01)); |
| 589 } else if (width > _BITS) { | 586 } else if (width > _BITS) { |
| 590 int m = _m.toSigned(width - _BITS); | 587 int m = _m.toSigned(width - _BITS); |
| 591 return m.isNegative | 588 return m.isNegative |
| 592 ? Int64._masked(_l, m, _MASK2) | 589 ? Int64._masked(_l, m, _MASK2) |
| 593 : Int64._masked(_l, m, 0); // Masking for type inferrer. | 590 : Int64._masked(_l, m, 0); // Masking for type inferrer. |
| 594 } else { | 591 } else { |
| 595 int l = _l.toSigned(width); | 592 int l = _l.toSigned(width); |
| 596 return l.isNegative | 593 return l.isNegative |
| 597 ? Int64._masked(l, _MASK, _MASK2) | 594 ? Int64._masked(l, _MASK, _MASK2) |
| 598 : Int64._masked(l, 0, 0); // Masking for type inferrer. | 595 : Int64._masked(l, 0, 0); // Masking for type inferrer. |
| 599 } | 596 } |
| 600 } | 597 } |
| 601 | 598 |
| 602 Int64 toUnsigned(int width) { | 599 Int64 toUnsigned(int width) { |
| 603 if (width < 0 || width > 64) throw new ArgumentError(width); | 600 if (width < 0 || width > 64) throw new RangeError.range(width, 0, 64); |
| 604 if (width > _BITS01) { | 601 if (width > _BITS01) { |
| 605 int h = _h.toUnsigned(width - _BITS01); | 602 int h = _h.toUnsigned(width - _BITS01); |
| 606 return Int64._masked(_l, _m, h); | 603 return Int64._masked(_l, _m, h); |
| 607 } else if (width > _BITS) { | 604 } else if (width > _BITS) { |
| 608 int m = _m.toUnsigned(width - _BITS); | 605 int m = _m.toUnsigned(width - _BITS); |
| 609 return Int64._masked(_l, m, 0); | 606 return Int64._masked(_l, m, 0); |
| 610 } else { | 607 } else { |
| 611 int l = _l.toUnsigned(width); | 608 int l = _l.toUnsigned(width); |
| 612 return Int64._masked(l, 0, 0); | 609 return Int64._masked(l, 0, 0); |
| 613 } | 610 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 Int64 digit_f = new Int64(0xf); | 674 Int64 digit_f = new Int64(0xf); |
| 678 while (!x.isZero) { | 675 while (!x.isZero) { |
| 679 int digit = x._l & 0xf; | 676 int digit = x._l & 0xf; |
| 680 hexStr = "${_hexDigit(digit)}$hexStr"; | 677 hexStr = "${_hexDigit(digit)}$hexStr"; |
| 681 x = x.shiftRightUnsigned(4); | 678 x = x.shiftRightUnsigned(4); |
| 682 } | 679 } |
| 683 return hexStr; | 680 return hexStr; |
| 684 } | 681 } |
| 685 | 682 |
| 686 String toRadixString(int radix) { | 683 String toRadixString(int radix) { |
| 687 if ((radix <= 1) || (radix > 36)) { | 684 return _toRadixString(Int32._validateRadix(radix)); |
| 688 throw new ArgumentError("Bad radix: $radix"); | |
| 689 } | |
| 690 return _toRadixString(radix); | |
| 691 } | 685 } |
| 692 | 686 |
| 693 String _toRadixString(int radix) { | 687 String _toRadixString(int radix) { |
| 694 int d0 = _l; | 688 int d0 = _l; |
| 695 int d1 = _m; | 689 int d1 = _m; |
| 696 int d2 = _h; | 690 int d2 = _h; |
| 697 | 691 |
| 698 if (d0 == 0 && d1 == 0 && d2 == 0) return '0'; | 692 if (d0 == 0 && d1 == 0 && d2 == 0) return '0'; |
| 699 | 693 |
| 700 String sign = ''; | 694 String sign = ''; |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 if (r0 == 0 && r1 == 0 && r2 == 0) { | 1026 if (r0 == 0 && r1 == 0 && r2 == 0) { |
| 1033 return ZERO; | 1027 return ZERO; |
| 1034 } else { | 1028 } else { |
| 1035 return _sub(b0, b1, b2, r0, r1, r2); | 1029 return _sub(b0, b1, b2, r0, r1, r2); |
| 1036 } | 1030 } |
| 1037 } else { | 1031 } else { |
| 1038 return _negate(r0, r1, r2); | 1032 return _negate(r0, r1, r2); |
| 1039 } | 1033 } |
| 1040 } | 1034 } |
| 1041 } | 1035 } |
| OLD | NEW |