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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 * [:((top & 0xffffffff) << 32) | (bottom & 0xffffffff):]. | 233 * [:((top & 0xffffffff) << 32) | (bottom & 0xffffffff):]. |
234 */ | 234 */ |
235 int64.fromInts(int top, int bottom) { | 235 int64.fromInts(int top, int bottom) { |
236 top &= 0xffffffff; | 236 top &= 0xffffffff; |
237 bottom &= 0xffffffff; | 237 bottom &= 0xffffffff; |
238 _l = bottom & _MASK; | 238 _l = bottom & _MASK; |
239 _m = ((top & 0xfff) << 10) | ((bottom >> _BITS) & 0x3ff); | 239 _m = ((top & 0xfff) << 10) | ((bottom >> _BITS) & 0x3ff); |
240 _h = (top >> 12) & _MASK_2; | 240 _h = (top >> 12) & _MASK_2; |
241 } | 241 } |
242 | 242 |
243 int64 _promote(other) { | 243 // Returns the [int64] representation of the specified value. Throws |
244 if (other == null) { | 244 // [ArgumentError] for non-integer arguments. |
245 throw new ArgumentError(null); | 245 int64 _promote(val) { |
246 } else if (other is intx) { | 246 if (val is int64) { |
247 other = other.toInt64(); | 247 return val; |
248 } else if (other is int) { | 248 } else if (val is int) { |
249 other = new int64.fromInt(other); | 249 return new int64.fromInt(val); |
| 250 } else if (val is int32) { |
| 251 return val.toInt64(); |
250 } | 252 } |
251 if (other is !int64) { | 253 throw new ArgumentError(val); |
252 throw new Exception("Can't promote $other to int64"); | |
253 } | |
254 return other; | |
255 } | 254 } |
256 | 255 |
257 int64 operator +(other) { | 256 int64 operator +(other) { |
258 int64 o = _promote(other); | 257 int64 o = _promote(other); |
259 int sum0 = _l + o._l; | 258 int sum0 = _l + o._l; |
260 int sum1 = _m + o._m + _shiftRight(sum0, _BITS); | 259 int sum1 = _m + o._m + _shiftRight(sum0, _BITS); |
261 int sum2 = _h + o._h + _shiftRight(sum1, _BITS); | 260 int sum2 = _h + o._h + _shiftRight(sum1, _BITS); |
262 | 261 |
263 int64 result = new int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2); | 262 int64 result = new int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2); |
264 return result; | 263 return result; |
265 } | 264 } |
266 | 265 |
267 int64 operator -(other) { | 266 int64 operator -(other) { |
268 int64 o = _promote(other); | 267 int64 o = _promote(other); |
269 | |
270 int sum0 = _l - o._l; | 268 int sum0 = _l - o._l; |
271 int sum1 = _m - o._m + _shiftRight(sum0, _BITS); | 269 int sum1 = _m - o._m + _shiftRight(sum0, _BITS); |
272 int sum2 = _h - o._h + _shiftRight(sum1, _BITS); | 270 int sum2 = _h - o._h + _shiftRight(sum1, _BITS); |
273 | 271 |
274 int64 result = new int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2); | 272 int64 result = new int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2); |
275 return result; | 273 return result; |
276 } | 274 } |
277 | 275 |
278 int64 operator -() { | 276 int64 operator -() { |
279 // Like 0 - this. | 277 // Like 0 - this. |
280 int sum0 = -_l; | 278 int sum0 = -_l; |
281 int sum1 = -_m + _shiftRight(sum0, _BITS); | 279 int sum1 = -_m + _shiftRight(sum0, _BITS); |
282 int sum2 = -_h + _shiftRight(sum1, _BITS); | 280 int sum2 = -_h + _shiftRight(sum1, _BITS); |
283 | 281 |
284 return new int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2); | 282 return new int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2); |
285 } | 283 } |
286 | 284 |
287 int64 operator *(other) { | 285 int64 operator *(other) { |
288 int64 o = _promote(other); | 286 int64 o = _promote(other); |
| 287 |
289 // Grab 13-bit chunks. | 288 // Grab 13-bit chunks. |
290 int a0 = _l & 0x1fff; | 289 int a0 = _l & 0x1fff; |
291 int a1 = (_l >> 13) | ((_m & 0xf) << 9); | 290 int a1 = (_l >> 13) | ((_m & 0xf) << 9); |
292 int a2 = (_m >> 4) & 0x1fff; | 291 int a2 = (_m >> 4) & 0x1fff; |
293 int a3 = (_m >> 17) | ((_h & 0xff) << 5); | 292 int a3 = (_m >> 17) | ((_h & 0xff) << 5); |
294 int a4 = (_h & 0xfff00) >> 8; | 293 int a4 = (_h & 0xfff00) >> 8; |
295 | 294 |
296 int b0 = o._l & 0x1fff; | 295 int b0 = o._l & 0x1fff; |
297 int b1 = (o._l >> 13) | ((o._m & 0xf) << 9); | 296 int b1 = (o._l >> 13) | ((o._m & 0xf) << 9); |
298 int b2 = (o._m >> 4) & 0x1fff; | 297 int b2 = (o._m >> 4) & 0x1fff; |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 } | 507 } |
509 | 508 |
510 return new int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK_2); | 509 return new int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK_2); |
511 } | 510 } |
512 | 511 |
513 /** | 512 /** |
514 * Returns [true] if this [int64] has the same numeric value as the | 513 * Returns [true] if this [int64] has the same numeric value as the |
515 * given object. The argument may be an [int] or an [intx]. | 514 * given object. The argument may be an [int] or an [intx]. |
516 */ | 515 */ |
517 bool operator ==(other) { | 516 bool operator ==(other) { |
518 if (other == null) { | 517 int64 o; |
519 return false; | 518 if (other is int64) { |
| 519 o = other; |
| 520 } else if (other is int) { |
| 521 o = new int64.fromInt(other); |
| 522 } else if (other is int32) { |
| 523 o = other.toInt64(); |
520 } | 524 } |
521 int64 o = _promote(other); | 525 if (o != null) { |
522 return _l == o._l && _m == o._m && _h == o._h; | 526 return _l == o._l && _m == o._m && _h == o._h; |
| 527 } |
| 528 return false; |
523 } | 529 } |
524 | 530 |
525 int compareTo(Comparable other) { | 531 int compareTo(Comparable other) { |
526 int64 o = _promote(other); | 532 int64 o = _promote(other); |
527 int signa = _h >> (_BITS2 - 1); | 533 int signa = _h >> (_BITS2 - 1); |
528 int signb = o._h >> (_BITS2 - 1); | 534 int signb = o._h >> (_BITS2 - 1); |
529 if (signa != signb) { | 535 if (signa != signb) { |
530 return signa == 0 ? 1 : -1; | 536 return signa == 0 ? 1 : -1; |
531 } | 537 } |
532 if (_h > o._h) { | 538 if (_h > o._h) { |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 b0 = _l; | 943 b0 = _l; |
938 b1 = _m; | 944 b1 = _m; |
939 b2 = _h & ((1 << (bits - _BITS01)) - 1); | 945 b2 = _h & ((1 << (bits - _BITS01)) - 1); |
940 } | 946 } |
941 | 947 |
942 _l = b0; | 948 _l = b0; |
943 _m = b1; | 949 _m = b1; |
944 _h = b2; | 950 _h = b2; |
945 } | 951 } |
946 | 952 |
947 int64 _divModByShift(int64 a, int bpower, bool negative, bool aIsCopy, | 953 static int64 _divModByShift(int64 a, int bpower, bool negative, bool aIsCopy, |
948 bool aIsNegative, bool computeRemainder) { | 954 bool aIsNegative, bool computeRemainder) { |
949 int64 c = a >> bpower; | 955 int64 c = a >> bpower; |
950 if (negative) { | 956 if (negative) { |
951 c._negate(); | 957 c._negate(); |
952 } | 958 } |
953 | 959 |
954 if (computeRemainder) { | 960 if (computeRemainder) { |
955 if (!aIsCopy) { | 961 if (!aIsCopy) { |
956 a = new int64._copy(a); | 962 a = new int64._copy(a); |
957 } | 963 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 if (h == 0 && m != 0 && l == 0) { | 996 if (h == 0 && m != 0 && l == 0) { |
991 return int32._numberOfTrailingZeros(m) + _BITS; | 997 return int32._numberOfTrailingZeros(m) + _BITS; |
992 } | 998 } |
993 if (h != 0 && m == 0 && l == 0) { | 999 if (h != 0 && m == 0 && l == 0) { |
994 return int32._numberOfTrailingZeros(h) + _BITS01; | 1000 return int32._numberOfTrailingZeros(h) + _BITS01; |
995 } | 1001 } |
996 | 1002 |
997 return -1; | 1003 return -1; |
998 } | 1004 } |
999 | 1005 |
1000 int64 _divMod(int64 a, int64 b, bool computeRemainder) { | 1006 static int64 _divMod(int64 a, int64 b, bool computeRemainder) { |
1001 if (b.isZero) { | 1007 if (b.isZero) { |
1002 throw new IntegerDivisionByZeroException(); | 1008 throw new IntegerDivisionByZeroException(); |
1003 } | 1009 } |
1004 if (a.isZero) { | 1010 if (a.isZero) { |
1005 if (computeRemainder) { | 1011 if (computeRemainder) { |
1006 _remainder = ZERO; | 1012 _remainder = ZERO; |
1007 } | 1013 } |
1008 return ZERO; | 1014 return ZERO; |
1009 } | 1015 } |
1010 // MIN_VALUE / MIN_VALUE = 1, anything other a / MIN_VALUE is 0. | 1016 // MIN_VALUE / MIN_VALUE = 1, anything other a / MIN_VALUE is 0. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1088 } | 1094 } |
1089 } | 1095 } |
1090 return ZERO; | 1096 return ZERO; |
1091 } | 1097 } |
1092 | 1098 |
1093 // Generate the quotient using bit-at-a-time long division. | 1099 // Generate the quotient using bit-at-a-time long division. |
1094 return _divModHelper(aIsCopy ? a : new int64._copy(a), b, negative, | 1100 return _divModHelper(aIsCopy ? a : new int64._copy(a), b, negative, |
1095 aIsNegative, aIsMinValue, computeRemainder); | 1101 aIsNegative, aIsMinValue, computeRemainder); |
1096 } | 1102 } |
1097 } | 1103 } |
OLD | NEW |