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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « lib/src/int32.dart ('k') | 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 12 matching lines...) Expand all
23 23
24 final int _l, _m, _h; 24 final int _l, _m, _h;
25 25
26 // Note: several functions require _BITS == 22 -- do not change this value. 26 // Note: several functions require _BITS == 22 -- do not change this value.
27 static const int _BITS = 22; 27 static const int _BITS = 22;
28 static const int _BITS01 = 44; // 2 * _BITS 28 static const int _BITS01 = 44; // 2 * _BITS
29 static const int _BITS2 = 20; // 64 - _BITS01 29 static const int _BITS2 = 20; // 64 - _BITS01
30 static const int _MASK = 4194303; // (1 << _BITS) - 1 30 static const int _MASK = 4194303; // (1 << _BITS) - 1
31 static const int _MASK2 = 1048575; // (1 << _BITS2) - 1 31 static const int _MASK2 = 1048575; // (1 << _BITS2) - 1
32 static const int _SIGN_BIT = 19; // _BITS2 - 1 32 static const int _SIGN_BIT = 19; // _BITS2 - 1
33 static const int _SIGN_BIT_MASK = 524288; // 1 << _SIGN_BIT 33 static const int _SIGN_BIT_MASK = 1 << _SIGN_BIT;
34 34
35 /** 35 /**
36 * The maximum positive value attainable by an [Int64], namely 36 * The maximum positive value attainable by an [Int64], namely
37 * 9,223,372,036,854,775,807. 37 * 9,223,372,036,854,775,807.
38 */ 38 */
39 static const Int64 MAX_VALUE = const Int64._bits(_MASK, _MASK, _MASK2 >> 1); 39 static const Int64 MAX_VALUE = const Int64._bits(_MASK, _MASK, _MASK2 >> 1);
40 40
41 /** 41 /**
42 * The minimum positive value attainable by an [Int64], namely 42 * The minimum positive value attainable by an [Int64], namely
43 * -9,223,372,036,854,775,808. 43 * -9,223,372,036,854,775,808.
(...skipping 19 matching lines...) Expand all
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, 83 int d0 = 0, d1 = 0, d2 = 0; // low, middle, high components.
87 d1 = 0,
88 d2 = 0; // low, middle, high components.
89 for (; i < s.length; i++) { 84 for (; i < s.length; i++) {
90 int c = s.codeUnitAt(i); 85 int c = s.codeUnitAt(i);
91 int digit = Int32._decodeDigit(c); 86 int digit = Int32._decodeDigit(c);
92 if (digit < 0 || digit >= radix) { 87 if (digit < 0 || digit >= radix) {
93 throw new FormatException("Non-radix char code: $c"); 88 throw new FormatException("Non-radix char code: $c");
94 } 89 }
95 90
96 // [radix] and [digit] are at most 6 bits, component is 22, so we can 91 // [radix] and [digit] are at most 6 bits, component is 22, so we can
97 // multiply and add within 30 bit temporary values. 92 // multiply and add within 30 bit temporary values.
98 d0 = d0 * radix + digit; 93 d0 = d0 * radix + digit;
99 int carry = d0 >> _BITS; 94 int carry = d0 >> _BITS;
100 d0 = _MASK & d0; 95 d0 = _MASK & d0;
101 96
102 d1 = d1 * radix + carry; 97 d1 = d1 * radix + carry;
103 carry = d1 >> _BITS; 98 carry = d1 >> _BITS;
104 d1 = _MASK & d1; 99 d1 = _MASK & d1;
105 100
106 d2 = d2 * radix + carry; 101 d2 = d2 * radix + carry;
107 d2 = _MASK2 & d2; 102 d2 = _MASK2 & d2;
108 } 103 }
109 104
110 if (negative) return _negate(d0, d1, d2); 105 if (negative) return _negate(d0, d1, d2);
111 106
112 return new Int64._bits(d0, d1, d2); 107 return Int64._masked(d0, d1, d2);
113 } 108 }
114 109
115 /** 110 /**
116 * Parses a decimal [String] and returns an [Int64]. 111 * Parses a decimal [String] and returns an [Int64].
117 */ 112 */
118 static Int64 parseInt(String s) => _parseRadix(s, 10); 113 static Int64 parseInt(String s) => _parseRadix(s, 10);
119 114
120 /** 115 /**
121 * Parses a hexadecimal [String] and returns an [Int64]. 116 * Parses a hexadecimal [String] and returns an [Int64].
122 */ 117 */
123 static Int64 parseHex(String s) => _parseRadix(s, 16); 118 static Int64 parseHex(String s) => _parseRadix(s, 16);
124 119
125 // 120 //
126 // Public constructors 121 // Public constructors
127 // 122 //
128 123
129 /** 124 /**
130 * Constructs an [Int64] with a given [int] value; zero by default. 125 * Constructs an [Int64] with a given [int] value; zero by default.
131 */ 126 */
132 factory Int64([int value = 0]) { 127 factory Int64([int value=0]) {
133 int v0 = 0, 128 int v0 = 0, v1 = 0, v2 = 0;
134 v1 = 0,
135 v2 = 0;
136 bool negative = false; 129 bool negative = false;
137 if (value < 0) { 130 if (value < 0) {
138 negative = true; 131 negative = true;
139 value = -value - 1; 132 value = -value - 1;
140 } 133 }
141 if (_haveBigInts) { 134 // Avoid using bitwise operations that in JavaScript coerce their input to
142 v0 = _MASK & value; 135 // 32 bits.
143 v1 = _MASK & (value >> _BITS); 136 v2 = value ~/ 17592186044416; // 2^44
144 v2 = _MASK2 & (value >> _BITS01); 137 value -= v2 * 17592186044416;
145 } else { 138 v1 = value ~/ 4194304; // 2^22
146 // Avoid using bitwise operations that coerce their input to 32 bits. 139 value -= v1 * 4194304;
147 v2 = value ~/ 17592186044416; // 2^44 140 v0 = value;
148 value -= v2 * 17592186044416;
149 v1 = value ~/ 4194304; // 2^22
150 value -= v1 * 4194304;
151 v0 = value;
152 }
153 141
154 if (negative) { 142 if (negative) {
155 v0 = ~v0; 143 v0 = ~v0;
156 v1 = ~v1; 144 v1 = ~v1;
157 v2 = ~v2; 145 v2 = ~v2;
158 } 146 }
159 return Int64._masked(v0, v1, v2); 147 return Int64._masked(v0, v1, v2);
160 } 148 }
161 149
162 factory Int64.fromBytes(List<int> bytes) { 150 factory Int64.fromBytes(List<int> bytes) {
(...skipping 27 matching lines...) Expand all
190 178
191 int bottom = bytes[4] & 0xff; 179 int bottom = bytes[4] & 0xff;
192 bottom <<= 8; 180 bottom <<= 8;
193 bottom |= bytes[5] & 0xff; 181 bottom |= bytes[5] & 0xff;
194 bottom <<= 8; 182 bottom <<= 8;
195 bottom |= bytes[6] & 0xff; 183 bottom |= bytes[6] & 0xff;
196 bottom <<= 8; 184 bottom <<= 8;
197 bottom |= bytes[7] & 0xff; 185 bottom |= bytes[7] & 0xff;
198 186
199 return new Int64.fromInts(top, bottom); 187 return new Int64.fromInts(top, bottom);
200 } 188 }
201 189
202 /** 190 /**
203 * Constructs an [Int64] from a pair of 32-bit integers having the value 191 * Constructs an [Int64] from a pair of 32-bit integers having the value
204 * [:((top & 0xffffffff) << 32) | (bottom & 0xffffffff):]. 192 * [:((top & 0xffffffff) << 32) | (bottom & 0xffffffff):].
205 */ 193 */
206 factory Int64.fromInts(int top, int bottom) { 194 factory Int64.fromInts(int top, int bottom) {
207 top &= 0xffffffff; 195 top &= 0xffffffff;
208 bottom &= 0xffffffff; 196 bottom &= 0xffffffff;
209 int d0 = bottom & _MASK; 197 int d0 = _MASK & bottom;
210 int d1 = ((top & 0xfff) << 10) | ((bottom >> _BITS) & 0x3ff); 198 int d1 = ((0xfff & top) << 10) | (0x3ff & (bottom >> _BITS));
211 int d2 = (top >> 12) & _MASK2; 199 int d2 = _MASK2 & (top >> 12);
212 return new Int64._bits(d0, d1, d2); 200 return Int64._masked(d0, d1, d2);
213 } 201 }
214 202
215 // Returns the [Int64] representation of the specified value. Throws 203 // Returns the [Int64] representation of the specified value. Throws
216 // [ArgumentError] for non-integer arguments. 204 // [ArgumentError] for non-integer arguments.
217 static Int64 _promote(val) { 205 static Int64 _promote(value) {
218 if (val is Int64) { 206 if (value is Int64) {
219 return val; 207 return value;
220 } else if (val is int) { 208 } else if (value is int) {
221 return new Int64(val); 209 return new Int64(value);
222 } else if (val is Int32) { 210 } else if (value is Int32) {
223 return val.toInt64(); 211 return value.toInt64();
224 } 212 }
225 throw new ArgumentError(val); 213 throw new ArgumentError.value(value);
226 } 214 }
227 215
228 Int64 operator +(other) { 216 Int64 operator +(other) {
229 Int64 o = _promote(other); 217 Int64 o = _promote(other);
230 int sum0 = _l + o._l; 218 int sum0 = _l + o._l;
231 int sum1 = _m + o._m + (sum0 >> _BITS); 219 int sum1 = _m + o._m + (sum0 >> _BITS);
232 int sum2 = _h + o._h + (sum1 >> _BITS); 220 int sum2 = _h + o._h + (sum1 >> _BITS);
233 return Int64._masked(sum0, sum1, sum2); 221 return Int64._masked(sum0, sum1, sum2);
234 } 222 }
235 223
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 int c13 = (p3 & 0x1f) << 17; 297 int c13 = (p3 & 0x1f) << 17;
310 int c1 = c10 + c11 + c12 + c13; 298 int c1 = c10 + c11 + c12 + c13;
311 299
312 int c22 = p2 >> 18; 300 int c22 = p2 >> 18;
313 int c23 = p3 >> 5; 301 int c23 = p3 >> 5;
314 int c24 = (p4 & 0xfff) << 8; 302 int c24 = (p4 & 0xfff) << 8;
315 int c2 = c22 + c23 + c24; 303 int c2 = c22 + c23 + c24;
316 304
317 // Propagate high bits from c0 -> c1, c1 -> c2. 305 // Propagate high bits from c0 -> c1, c1 -> c2.
318 c1 += c0 >> _BITS; 306 c1 += c0 >> _BITS;
319 c0 &= _MASK;
320 c2 += c1 >> _BITS; 307 c2 += c1 >> _BITS;
321 c1 &= _MASK;
322 c2 &= _MASK2;
323 308
324 return new Int64._bits(c0, c1, c2); 309 return Int64._masked(c0, c1, c2);
325 } 310 }
326 311
327 Int64 operator %(other) => _divide(this, other, _RETURN_MOD); 312 Int64 operator %(other) => _divide(this, other, _RETURN_MOD);
328 313
329 Int64 operator ~/(other) => _divide(this, other, _RETURN_DIV); 314 Int64 operator ~/(other) => _divide(this, other, _RETURN_DIV);
330 315
331 Int64 remainder(other) => _divide(this, other, _RETURN_REM); 316 Int64 remainder(other) => _divide(this, other, _RETURN_REM);
332 317
333 Int64 operator &(other) { 318 Int64 operator &(other) {
334 Int64 o = _promote(other); 319 Int64 o = _promote(other);
335 int a0 = _l & o._l; 320 int a0 = _l & o._l;
336 int a1 = _m & o._m; 321 int a1 = _m & o._m;
337 int a2 = _h & o._h; 322 int a2 = _h & o._h;
338 return new Int64._bits(a0, a1, a2); 323 return Int64._masked(a0, a1, a2);
339 } 324 }
340 325
341 Int64 operator |(other) { 326 Int64 operator |(other) {
342 Int64 o = _promote(other); 327 Int64 o = _promote(other);
343 int a0 = _l | o._l; 328 int a0 = _l | o._l;
344 int a1 = _m | o._m; 329 int a1 = _m | o._m;
345 int a2 = _h | o._h; 330 int a2 = _h | o._h;
346 return new Int64._bits(a0, a1, a2); 331 return Int64._masked(a0, a1, a2);
347 } 332 }
348 333
349 Int64 operator ^(other) { 334 Int64 operator ^(other) {
350 Int64 o = _promote(other); 335 Int64 o = _promote(other);
351 int a0 = _l ^ o._l; 336 int a0 = _l ^ o._l;
352 int a1 = _m ^ o._m; 337 int a1 = _m ^ o._m;
353 int a2 = _h ^ o._h; 338 int a2 = _h ^ o._h;
354 return new Int64._bits(a0, a1, a2); 339 return Int64._masked(a0, a1, a2);
355 } 340 }
356 341
357 Int64 operator ~() { 342 Int64 operator ~() {
358 return Int64._masked(~_l, ~_m, ~_h); 343 return Int64._masked(~_l, ~_m, ~_h);
359 } 344 }
360 345
361 Int64 operator <<(int n) { 346 Int64 operator <<(int n) {
362 if (n < 0) { 347 if (n < 0) {
363 throw new ArgumentError(n); 348 throw new ArgumentError.value(n);
364 } 349 }
365 n &= 63; 350 n &= 63;
366 351
367 int res0, res1, res2; 352 int res0, res1, res2;
368 if (n < _BITS) { 353 if (n < _BITS) {
369 res0 = _l << n; 354 res0 = _l << n;
370 res1 = (_m << n) | (_l >> (_BITS - n)); 355 res1 = (_m << n) | (_l >> (_BITS - n));
371 res2 = (_h << n) | (_m >> (_BITS - n)); 356 res2 = (_h << n) | (_m >> (_BITS - n));
372 } else if (n < _BITS01) { 357 } else if (n < _BITS01) {
373 res0 = 0; 358 res0 = 0;
374 res1 = _l << (n - _BITS); 359 res1 = _l << (n - _BITS);
375 res2 = (_m << (n - _BITS)) | (_l >> (_BITS01 - n)); 360 res2 = (_m << (n - _BITS)) | (_l >> (_BITS01 - n));
376 } else { 361 } else {
377 res0 = 0; 362 res0 = 0;
378 res1 = 0; 363 res1 = 0;
379 res2 = _l << (n - _BITS01); 364 res2 = _l << (n - _BITS01);
380 } 365 }
381 366
382 return Int64._masked(res0, res1, res2); 367 return Int64._masked(res0, res1, res2);
383 } 368 }
384 369
385 Int64 operator >>(int n) { 370 Int64 operator >>(int n) {
386 if (n < 0) { 371 if (n < 0) {
387 throw new ArgumentError(n); 372 throw new ArgumentError.value(n);
388 } 373 }
389 n &= 63; 374 n &= 63;
390 375
391 int res0, res1, res2; 376 int res0, res1, res2;
392 377
393 // Sign extend h(a). 378 // Sign extend h(a).
394 int a2 = _h; 379 int a2 = _h;
395 bool negative = (a2 & _SIGN_BIT_MASK) != 0; 380 bool negative = (a2 & _SIGN_BIT_MASK) != 0;
396 if (negative && _MASK > _MASK2) { 381 if (negative && _MASK > _MASK2) {
397 // Add extra one bits on the left so the sign gets shifted into the wider 382 // Add extra one bits on the left so the sign gets shifted into the wider
(...skipping 22 matching lines...) Expand all
420 if (negative) { 405 if (negative) {
421 res0 |= _MASK & ~(_MASK >> (n - _BITS01)); 406 res0 |= _MASK & ~(_MASK >> (n - _BITS01));
422 } 407 }
423 } 408 }
424 409
425 return Int64._masked(res0, res1, res2); 410 return Int64._masked(res0, res1, res2);
426 } 411 }
427 412
428 Int64 shiftRightUnsigned(int n) { 413 Int64 shiftRightUnsigned(int n) {
429 if (n < 0) { 414 if (n < 0) {
430 throw new ArgumentError(n); 415 throw new ArgumentError.value(n);
431 } 416 }
432 n &= 63; 417 n &= 63;
433 418
434 int res0, res1, res2; 419 int res0, res1, res2;
435 int a2 = _MASK2 & _h; // Ensure a2 is positive. 420 int a2 = _MASK2 & _h; // Ensure a2 is positive.
436 if (n < _BITS) { 421 if (n < _BITS) {
437 res2 = a2 >> n; 422 res2 = a2 >> n;
438 res1 = (_m >> n) | (a2 << (_BITS - n)); 423 res1 = (_m >> n) | (a2 << (_BITS - n));
439 res0 = (_l >> n) | (_m << (_BITS - n)); 424 res0 = (_l >> n) | (_m << (_BITS - n));
440 } else if (n < _BITS01) { 425 } else if (n < _BITS01) {
(...skipping 25 matching lines...) Expand all
466 o = new Int64(other); 451 o = new Int64(other);
467 } else if (other is Int32) { 452 } else if (other is Int32) {
468 o = other.toInt64(); 453 o = other.toInt64();
469 } 454 }
470 if (o != null) { 455 if (o != null) {
471 return _l == o._l && _m == o._m && _h == o._h; 456 return _l == o._l && _m == o._m && _h == o._h;
472 } 457 }
473 return false; 458 return false;
474 } 459 }
475 460
476 int compareTo(Comparable other) { 461 int compareTo(Comparable other) =>_compareTo(other);
462
463 int _compareTo(other) {
477 Int64 o = _promote(other); 464 Int64 o = _promote(other);
478 int signa = _h >> (_BITS2 - 1); 465 int signa = _h >> (_BITS2 - 1);
479 int signb = o._h >> (_BITS2 - 1); 466 int signb = o._h >> (_BITS2 - 1);
480 if (signa != signb) { 467 if (signa != signb) {
481 return signa == 0 ? 1 : -1; 468 return signa == 0 ? 1 : -1;
482 } 469 }
483 if (_h > o._h) { 470 if (_h > o._h) {
484 return 1; 471 return 1;
485 } else if (_h < o._h) { 472 } else if (_h < o._h) {
486 return -1; 473 return -1;
487 } 474 }
488 if (_m > o._m) { 475 if (_m > o._m) {
489 return 1; 476 return 1;
490 } else if (_m < o._m) { 477 } else if (_m < o._m) {
491 return -1; 478 return -1;
492 } 479 }
493 if (_l > o._l) { 480 if (_l > o._l) {
494 return 1; 481 return 1;
495 } else if (_l < o._l) { 482 } else if (_l < o._l) {
496 return -1; 483 return -1;
497 } 484 }
498 return 0; 485 return 0;
499 } 486 }
500 487
501 bool operator <(other) { 488 bool operator <(other) => _compareTo(other) < 0;
502 return this.compareTo(other) < 0; 489 bool operator <=(other) => _compareTo(other) <= 0;
503 } 490 bool operator >(other) => this._compareTo(other) > 0;
504 491 bool operator >=(other) => _compareTo(other) >= 0;
505 bool operator <=(other) {
506 return this.compareTo(other) <= 0;
507 }
508
509 bool operator >(other) {
510 return this.compareTo(other) > 0;
511 }
512
513 bool operator >=(other) {
514 return this.compareTo(other) >= 0;
515 }
516 492
517 bool get isEven => (_l & 0x1) == 0; 493 bool get isEven => (_l & 0x1) == 0;
518 bool get isMaxValue => (_h == _MASK2 >> 1) && _m == _MASK && _l == _MASK; 494 bool get isMaxValue => (_h == _MASK2 >> 1) && _m == _MASK && _l == _MASK;
519 bool get isMinValue => _h == _SIGN_BIT_MASK && _m == 0 && _l == 0; 495 bool get isMinValue => _h == _SIGN_BIT_MASK && _m == 0 && _l == 0;
520 bool get isNegative => (_h & _SIGN_BIT_MASK) != 0; 496 bool get isNegative => (_h & _SIGN_BIT_MASK) != 0;
521 bool get isOdd => (_l & 0x1) == 1; 497 bool get isOdd => (_l & 0x1) == 1;
522 bool get isZero => _h == 0 && _m == 0 && _l == 0; 498 bool get isZero => _h == 0 && _m == 0 && _l == 0;
523 499
524 int get bitLength { 500 int get bitLength {
525 if (isZero) return 0; 501 if (isZero) return 0;
526 int a0 = _l, 502 int a0 = _l, a1 = _m, a2 = _h;
527 a1 = _m,
528 a2 = _h;
529 if (isNegative) { 503 if (isNegative) {
530 a0 = _MASK & ~a0; 504 a0 = _MASK & ~a0;
531 a1 = _MASK & ~a1; 505 a1 = _MASK & ~a1;
532 a2 = _MASK2 & ~a2; 506 a2 = _MASK2 & ~a2;
533 } 507 }
534 if (a2 != 0) return _BITS01 + a2.bitLength; 508 if (a2 != 0) return _BITS01 + a2.bitLength;
535 if (a1 != 0) return _BITS + a1.bitLength; 509 if (a1 != 0) return _BITS + a1.bitLength;
536 return a0.bitLength; 510 return a0.bitLength;
537 } 511 }
538 512
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 568
595 zeros = Int32._numberOfTrailingZeros(_h); 569 zeros = Int32._numberOfTrailingZeros(_h);
596 if (zeros < 32) { 570 if (zeros < 32) {
597 return _BITS01 + zeros; 571 return _BITS01 + zeros;
598 } 572 }
599 // All zeros 573 // All zeros
600 return 64; 574 return 64;
601 } 575 }
602 576
603 Int64 toSigned(int width) { 577 Int64 toSigned(int width) {
604 if (width < 1 || width > 64) throw new ArgumentError(width); 578 if (width < 1 || width > 64) throw new RangeError.range(width, 1, 64);
605 if (width > _BITS01) { 579 if (width > _BITS01) {
606 return Int64._masked(_l, _m, _h.toSigned(width - _BITS01)); 580 return Int64._masked(_l, _m, _h.toSigned(width - _BITS01));
607 } else if (width > _BITS) { 581 } else if (width > _BITS) {
608 int m = _m.toSigned(width - _BITS); 582 int m = _m.toSigned(width - _BITS);
609 return m.isNegative 583 return m.isNegative
610 ? Int64._masked(_l, m, _MASK2) 584 ? Int64._masked(_l, m, _MASK2)
611 : Int64._masked(_l, m, 0); // Masking for type inferrer. 585 : Int64._masked(_l, m, 0); // Masking for type inferrer.
612 } else { 586 } else {
613 int l = _l.toSigned(width); 587 int l = _l.toSigned(width);
614 return l.isNegative 588 return l.isNegative
615 ? Int64._masked(l, _MASK, _MASK2) 589 ? Int64._masked(l, _MASK, _MASK2)
616 : Int64._masked(l, 0, 0); // Masking for type inferrer. 590 : Int64._masked(l, 0, 0); // Masking for type inferrer.
617 } 591 }
618 } 592 }
619 593
620 Int64 toUnsigned(int width) { 594 Int64 toUnsigned(int width) {
621 if (width < 0 || width > 64) throw new ArgumentError(width); 595 if (width < 0 || width > 64) throw new RangeError.range(width, 0, 64);
622 if (width > _BITS01) { 596 if (width > _BITS01) {
623 int h = _h.toUnsigned(width - _BITS01); 597 int h = _h.toUnsigned(width - _BITS01);
624 return Int64._masked(_l, _m, h); 598 return Int64._masked(_l, _m, h);
625 } else if (width > _BITS) { 599 } else if (width > _BITS) {
626 int m = _m.toUnsigned(width - _BITS); 600 int m = _m.toUnsigned(width - _BITS);
627 return Int64._masked(_l, m, 0); 601 return Int64._masked(_l, m, 0);
628 } else { 602 } else {
629 int l = _l.toUnsigned(width); 603 int l = _l.toUnsigned(width);
630 return Int64._masked(l, 0, 0); 604 return Int64._masked(l, 0, 0);
631 } 605 }
(...skipping 11 matching lines...) Expand all
643 result[7] = (_h >> 12) & 0xff; 617 result[7] = (_h >> 12) & 0xff;
644 return result; 618 return result;
645 } 619 }
646 620
647 double toDouble() => toInt().toDouble(); 621 double toDouble() => toInt().toDouble();
648 622
649 int toInt() { 623 int toInt() {
650 int l = _l; 624 int l = _l;
651 int m = _m; 625 int m = _m;
652 int h = _h; 626 int h = _h;
653 bool negative = false; 627 // In the sum we add least significant to most significant so that in
628 // JavaScript double arithmetic rounding occurs on only the last addition.
654 if ((_h & _SIGN_BIT_MASK) != 0) { 629 if ((_h & _SIGN_BIT_MASK) != 0) {
655 l = _MASK & ~_l; 630 l = _MASK & ~_l;
656 m = _MASK & ~_m; 631 m = _MASK & ~_m;
657 h = _MASK2 & ~_h; 632 h = _MASK2 & ~_h;
658 negative = true; 633 return -((1 + l) + (4194304 * m) + (17592186044416 * h));
659 }
660
661 if (_haveBigInts) {
662 int result = (h << _BITS01) | (m << _BITS) | l;
663 return negative ? -result - 1 : result;
664 } else { 634 } else {
665 if (negative) { 635 return l + (4194304 * m) + (17592186044416 * h);
666 return -((l + 1) + (m * 4194304) + (h * 17592186044416));
667 } else {
668 return (l + (m * 4194304)) + (h * 17592186044416);
669 }
670 } 636 }
671 } 637 }
672 638
673 /** 639 /**
674 * Returns an [Int32] containing the low 32 bits of this [Int64]. 640 * Returns an [Int32] containing the low 32 bits of this [Int64].
675 */ 641 */
676 Int32 toInt32() { 642 Int32 toInt32() {
677 return new Int32(((_m & 0x3ff) << _BITS) | _l); 643 return new Int32(((_m & 0x3ff) << _BITS) | _l);
678 } 644 }
679 645
680 /** 646 /**
681 * Returns [this]. 647 * Returns [this].
682 */ 648 */
683 Int64 toInt64() => this; 649 Int64 toInt64() => this;
684 650
685 /** 651 /**
686 * Returns the value of this [Int64] as a decimal [String]. 652 * Returns the value of this [Int64] as a decimal [String].
687 */ 653 */
688 String toString() => _toRadixString(10); 654 String toString() => _toRadixString(10);
689 655
690 // TODO(rice) - Make this faster by avoiding arithmetic. 656 // TODO(rice) - Make this faster by avoiding arithmetic.
691 String toHexString() { 657 String toHexString() {
692 if (isZero) return "0"; 658 if (isZero) return "0";
693 Int64 x = this; 659 Int64 x = this;
694 String hexStr = ""; 660 String hexStr = "";
695 Int64 digit_f = new Int64(0xf);
696 while (!x.isZero) { 661 while (!x.isZero) {
697 int digit = x._l & 0xf; 662 int digit = x._l & 0xf;
698 hexStr = "${_hexDigit(digit)}$hexStr"; 663 hexStr = "${_hexDigit(digit)}$hexStr";
699 x = x.shiftRightUnsigned(4); 664 x = x.shiftRightUnsigned(4);
700 } 665 }
701 return hexStr; 666 return hexStr;
702 } 667 }
703 668
704 String toRadixString(int radix) { 669 String toRadixString(int radix) {
705 if ((radix <= 1) || (radix > 36)) { 670 return _toRadixString(Int32._validateRadix(radix));
706 throw new ArgumentError("Bad radix: $radix");
707 }
708 return _toRadixString(radix);
709 } 671 }
710 672
711 String _toRadixString(int radix) { 673 String _toRadixString(int radix) {
712 int d0 = _l; 674 int d0 = _l;
713 int d1 = _m; 675 int d1 = _m;
714 int d2 = _h; 676 int d2 = _h;
715 677
716 if (d0 == 0 && d1 == 0 && d2 == 0) return '0'; 678 if (d0 == 0 && d1 == 0 && d2 == 0) return '0';
717 679
718 String sign = ''; 680 String sign = '';
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 int fatRadix = _fatRadixTable[radix]; 719 int fatRadix = _fatRadixTable[radix];
758 720
759 // Generate chunks of digits. In radix 10, generate 6 digits per chunk. 721 // Generate chunks of digits. In radix 10, generate 6 digits per chunk.
760 // 722 //
761 // This loop generates at most 3 chunks, so we store the chunks in locals 723 // This loop generates at most 3 chunks, so we store the chunks in locals
762 // rather than a list. We are trying to generate digits 20 bits at a time 724 // rather than a list. We are trying to generate digits 20 bits at a time
763 // until we have only 30 bits left. 20 + 20 + 30 > 64 would imply that we 725 // until we have only 30 bits left. 20 + 20 + 30 > 64 would imply that we
764 // need only two chunks, but radix values 17-19 and 33-36 generate only 15 726 // need only two chunks, but radix values 17-19 and 33-36 generate only 15
765 // or 16 bits per iteration, so sometimes the third chunk is needed. 727 // or 16 bits per iteration, so sometimes the third chunk is needed.
766 728
767 String chunk1 = "", 729 String chunk1 = "", chunk2 = "", chunk3 = "";
768 chunk2 = "",
769 chunk3 = "";
770 730
771 while (!(d4 == 0 && d3 == 0)) { 731 while (!(d4 == 0 && d3 == 0)) {
772 int q = d4 ~/ fatRadix; 732 int q = d4 ~/ fatRadix;
773 int r = d4 - q * fatRadix; 733 int r = d4 - q * fatRadix;
774 d4 = q; 734 d4 = q;
775 d3 += r << 10; 735 d3 += r << 10;
776 736
777 q = d3 ~/ fatRadix; 737 q = d3 ~/ fatRadix;
778 r = d3 - q * fatRadix; 738 r = d3 - q * fatRadix;
779 d3 = q; 739 d3 = q;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 int diff0 = a0 - b0; 820 int diff0 = a0 - b0;
861 int diff1 = a1 - b1 - ((diff0 >> _BITS) & 1); 821 int diff1 = a1 - b1 - ((diff0 >> _BITS) & 1);
862 int diff2 = a2 - b2 - ((diff1 >> _BITS) & 1); 822 int diff2 = a2 - b2 - ((diff1 >> _BITS) & 1);
863 return _masked(diff0, diff1, diff2); 823 return _masked(diff0, diff1, diff2);
864 } 824 }
865 825
866 static Int64 _negate(int b0, int b1, int b2) { 826 static Int64 _negate(int b0, int b1, int b2) {
867 return _sub(0, 0, 0, b0, b1, b2); 827 return _sub(0, 0, 0, b0, b1, b2);
868 } 828 }
869 829
870 // Determine whether the platform supports ints greater than 2^53
871 // without loss of precision.
872 static bool _haveBigIntsCached = null;
873
874 static bool get _haveBigInts {
875 if (_haveBigIntsCached == null) {
876 var x = 9007199254740992;
877 // Defeat compile-time constant folding.
878 if (2 + 2 != 4) {
879 x = 0;
880 }
881 var y = x + 1;
882 var same = y == x;
883 _haveBigIntsCached = !same;
884 }
885 return _haveBigIntsCached;
886 }
887
888 String _hexDigit(int digit) => "0123456789ABCDEF"[digit]; 830 String _hexDigit(int digit) => "0123456789ABCDEF"[digit];
889 831
890 // Work around dart2js bugs with negative arguments to '>>' operator. 832 // Work around dart2js bugs with negative arguments to '>>' operator.
891 static int _shiftRight(int x, int n) { 833 static int _shiftRight(int x, int n) {
892 if (x >= 0) { 834 if (x >= 0) {
893 return x >> n; 835 return x >> n;
894 } else { 836 } else {
895 int shifted = x >> n; 837 int shifted = x >> n;
896 if (shifted >= 0x80000000) { 838 if (shifted >= 0x80000000) {
897 shifted -= 4294967296; 839 shifted -= 4294967296;
(...skipping 25 matching lines...) Expand all
923 int b2 = b._h; 865 int b2 = b._h;
924 return _divideHelper(a0, a1, a2, aNeg, b0, b1, b2, bNeg, what); 866 return _divideHelper(a0, a1, a2, aNeg, b0, b1, b2, bNeg, what);
925 } 867 }
926 868
927 static const _RETURN_DIV = 1; 869 static const _RETURN_DIV = 1;
928 static const _RETURN_REM = 2; 870 static const _RETURN_REM = 2;
929 static const _RETURN_MOD = 3; 871 static const _RETURN_MOD = 3;
930 872
931 static _divideHelper( 873 static _divideHelper(
932 // up to 64 bits unsigned in a2/a1/a0 and b2/b1/b0 874 // up to 64 bits unsigned in a2/a1/a0 and b2/b1/b0
933 int a0, int a1, int a2, bool aNeg, // input A. 875 int a0, int a1, int a2, bool aNeg, // input A.
934 int b0, int b1, int b2, bool bNeg, // input B. 876 int b0, int b1, int b2, bool bNeg, // input B.
935 int what) { 877 int what) {
936 int q0 = 0, 878 int q0 = 0, q1 = 0, q2 = 0; // result Q.
937 q1 = 0, 879 int r0 = 0, r1 = 0, r2 = 0; // result R.
938 q2 = 0; // result Q.
939 int r0 = 0,
940 r1 = 0,
941 r2 = 0; // result R.
942 880
943 if (b2 == 0 && b1 == 0 && b0 < (1 << (30 - _BITS))) { 881 if (b2 == 0 && b1 == 0 && b0 < (1 << (30 - _BITS))) {
944 // Small divisor can be handled by single-digit division within Smi range. 882 // Small divisor can be handled by single-digit division within Smi range.
945 // 883 //
946 // Handling small divisors here helps the estimate version below by 884 // Handling small divisors here helps the estimate version below by
947 // handling cases where the estimate is off by more than a small amount. 885 // handling cases where the estimate is off by more than a small amount.
948 886
949 q2 = a2 ~/ b0; 887 q2 = a2 ~/ b0;
950 int carry = a2 - q2 * b0; 888 int carry = a2 - q2 * b0;
951 int d1 = a1 + (carry << _BITS); 889 int d1 = a1 + (carry << _BITS);
(...skipping 27 matching lines...) Expand all
979 // Extract components of [qd] using double arithmetic. 917 // Extract components of [qd] using double arithmetic.
980 double q2d = (qd / K2).floorToDouble(); 918 double q2d = (qd / K2).floorToDouble();
981 qd = qd - K2 * q2d; 919 qd = qd - K2 * q2d;
982 double q1d = (qd / K1).floorToDouble(); 920 double q1d = (qd / K1).floorToDouble();
983 double q0d = qd - K1 * q1d; 921 double q0d = qd - K1 * q1d;
984 q2 = q2d.toInt(); 922 q2 = q2d.toInt();
985 q1 = q1d.toInt(); 923 q1 = q1d.toInt();
986 q0 = q0d.toInt(); 924 q0 = q0d.toInt();
987 925
988 assert(q0 + K1 * q1 + K2 * q2 == (ad / bd).floorToDouble()); 926 assert(q0 + K1 * q1 + K2 * q2 == (ad / bd).floorToDouble());
989 assert(q2 == 0 || b2 == 0); // Q and B can't both be big since Q*B <= A. 927 assert(q2 == 0 || b2 == 0); // Q and B can't both be big since Q*B <= A.
990 928
991 // P = Q * B, using doubles to hold intermediates. 929 // P = Q * B, using doubles to hold intermediates.
992 // We don't need all partial sums since Q*B <= A. 930 // We don't need all partial sums since Q*B <= A.
993 double p0d = q0d * b0; 931 double p0d = q0d * b0;
994 double p0carry = (p0d / K1).floorToDouble(); 932 double p0carry = (p0d / K1).floorToDouble();
995 p0d = p0d - p0carry * K1; 933 p0d = p0d - p0carry * K1;
996 double p1d = q1d * b0 + q0d * b1 + p0carry; 934 double p1d = q1d * b0 + q0d * b1 + p0carry;
997 double p1carry = (p1d / K1).floorToDouble(); 935 double p1carry = (p1d / K1).floorToDouble();
998 p1d = p1d - p1carry * K1; 936 p1d = p1d - p1carry * K1;
999 double p2d = q2d * b0 + q1d * b1 + q0d * b2 + p1carry; 937 double p2d = q2d * b0 + q1d * b1 + q0d * b2 + p1carry;
1000 assert(p2d <= _MASK2); // No partial sum overflow. 938 assert(p2d <= _MASK2); // No partial sum overflow.
1001 939
1002 // R = A - P 940 // R = A - P
1003 int diff0 = a0 - p0d.toInt(); 941 int diff0 = a0 - p0d.toInt();
1004 int diff1 = a1 - p1d.toInt() - ((diff0 >> _BITS) & 1); 942 int diff1 = a1 - p1d.toInt() - ((diff0 >> _BITS) & 1);
1005 int diff2 = a2 - p2d.toInt() - ((diff1 >> _BITS) & 1); 943 int diff2 = a2 - p2d.toInt() - ((diff1 >> _BITS) & 1);
1006 r0 = _MASK & diff0; 944 r0 = _MASK & diff0;
1007 r1 = _MASK & diff1; 945 r1 = _MASK & diff1;
1008 r2 = _MASK2 & diff2; 946 r2 = _MASK2 & diff2;
1009 947
1010 // while (R < 0 || R >= B) 948 // while (R < 0 || R >= B)
1011 // adjust R towards [0, B) 949 // adjust R towards [0, B)
1012 while (r2 >= _SIGN_BIT_MASK || 950 while (
951 r2 >= _SIGN_BIT_MASK ||
1013 r2 > b2 || 952 r2 > b2 ||
1014 (r2 == b2 && (r1 > b1 || (r1 == b1 && r0 >= b0)))) { 953 (r2 == b2 && (r1 > b1 || (r1 == b1 && r0 >= b0)))) {
1015 // Direction multiplier for adjustment. 954 // Direction multiplier for adjustment.
1016 int m = (r2 & _SIGN_BIT_MASK) == 0 ? 1 : -1; 955 int m = (r2 & _SIGN_BIT_MASK) == 0 ? 1 : -1;
1017 // R = R - B or R = R + B 956 // R = R - B or R = R + B
1018 int d0 = r0 - m * b0; 957 int d0 = r0 - m * b0;
1019 int d1 = r1 - m * (b1 + ((d0 >> _BITS) & 1)); 958 int d1 = r1 - m * (b1 + ((d0 >> _BITS) & 1));
1020 int d2 = r2 - m * (b2 + ((d1 >> _BITS) & 1)); 959 int d2 = r2 - m * (b2 + ((d1 >> _BITS) & 1));
1021 r0 = _MASK & d0; 960 r0 = _MASK & d0;
1022 r1 = _MASK & d1; 961 r1 = _MASK & d1;
1023 r2 = _MASK2 & d2; 962 r2 = _MASK2 & d2;
1024 963
1025 // Q = Q + 1 or Q = Q - 1 964 // Q = Q + 1 or Q = Q - 1
1026 d0 = q0 + m; 965 d0 = q0 + m;
1027 d1 = q1 + m * ((d0 >> _BITS) & 1); 966 d1 = q1 + m * ((d0 >> _BITS) & 1);
1028 d2 = q2 + m * ((d1 >> _BITS) & 1); 967 d2 = q2 + m * ((d1 >> _BITS) & 1);
1029 q0 = _MASK & d0; 968 q0 = _MASK & d0;
1030 q1 = _MASK & d1; 969 q1 = _MASK & d1;
1031 q2 = _MASK2 & d2; 970 q2 = _MASK2 & d2;
1032 } 971 }
1033 } 972 }
1034 973
1035 // 0 <= R < B 974 // 0 <= R < B
1036 assert(Int64.ZERO <= new Int64._bits(r0, r1, r2)); 975 assert(Int64.ZERO <= new Int64._bits(r0, r1, r2));
1037 assert(r2 < b2 || // Handles case where B = -(MIN_VALUE) 976 assert(r2 < b2 || // Handles case where B = -(MIN_VALUE)
1038 new Int64._bits(r0, r1, r2) < new Int64._bits(b0, b1, b2)); 977 new Int64._bits(r0, r1, r2) < new Int64._bits(b0, b1, b2));
1039 978
1040 assert(what == _RETURN_DIV || what == _RETURN_MOD || what == _RETURN_REM); 979 assert(what == _RETURN_DIV || what == _RETURN_MOD || what == _RETURN_REM);
1041 if (what == _RETURN_DIV) { 980 if (what == _RETURN_DIV) {
1042 if (aNeg != bNeg) return _negate(q0, q1, q2); 981 if (aNeg != bNeg) return _negate(q0, q1, q2);
1043 return Int64._masked(q0, q1, q2); // Masking for type inferrer. 982 return Int64._masked(q0, q1, q2); // Masking for type inferrer.
1044 } 983 }
1045 984
1046 if (!aNeg) { 985 if (!aNeg) {
1047 return new Int64._bits(_MASK & r0, r1, r2); // Masking for type inferrer. 986 return Int64._masked(r0, r1, r2); // Masking for type inferrer.
1048 } 987 }
1049 988
1050 if (what == _RETURN_MOD) { 989 if (what == _RETURN_MOD) {
1051 if (r0 == 0 && r1 == 0 && r2 == 0) { 990 if (r0 == 0 && r1 == 0 && r2 == 0) {
1052 return ZERO; 991 return ZERO;
1053 } else { 992 } else {
1054 return _sub(b0, b1, b2, r0, r1, r2); 993 return _sub(b0, b1, b2, r0, r1, r2);
1055 } 994 }
1056 } else { 995 } else {
1057 return _negate(r0, r1, r2); 996 return _negate(r0, r1, r2);
1058 } 997 }
1059 } 998 }
1060 } 999 }
OLDNEW
« 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