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 |