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

Side by Side Diff: runtime/lib/bigint.dart

Issue 2759973004: Fix observatory tests broken by running dartfmt. Temporarily reverted formatting for evaluate_activ… (Closed)
Patch Set: Created 3 years, 9 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 | « runtime/lib/async_patch.dart ('k') | runtime/lib/bool_patch.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 import 'dart:typed_data' show Uint32List; 5 import 'dart:typed_data' show Uint32List;
6 6
7 // Copyright 2009 The Go Authors. All rights reserved. 7 // Copyright 2009 The Go Authors. All rights reserved.
8 // Use of this source code is governed by a BSD-style 8 // Use of this source code is governed by a BSD-style
9 // license that can be found in the LICENSE file. 9 // license that can be found in the LICENSE file.
10 10
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 } 112 }
113 var digits = new Uint32List(2); 113 var digits = new Uint32List(2);
114 digits[0] = l; 114 digits[0] = l;
115 digits[1] = h; 115 digits[1] = h;
116 return new _Bigint(neg, 2, digits); 116 return new _Bigint(neg, 2, digits);
117 } 117 }
118 118
119 // Allocate an array of the given length (+1 for at least one leading zero 119 // Allocate an array of the given length (+1 for at least one leading zero
120 // digit if odd) and copy digits[from..to-1] starting at index 0, followed by 120 // digit if odd) and copy digits[from..to-1] starting at index 0, followed by
121 // leading zero digits. 121 // leading zero digits.
122 static Uint32List _cloneDigits(Uint32List digits, int from, int to, 122 static Uint32List _cloneDigits(
123 int length) { 123 Uint32List digits, int from, int to, int length) {
124 length += length & 1; // Even number of digits. 124 length += length & 1; // Even number of digits.
125 var r_digits = new Uint32List(length); 125 var r_digits = new Uint32List(length);
126 var n = to - from; 126 var n = to - from;
127 for (var i = 0; i < n; i++) { 127 for (var i = 0; i < n; i++) {
128 r_digits[i] = digits[from + i]; 128 r_digits[i] = digits[from + i];
129 } 129 }
130 return r_digits; 130 return r_digits;
131 } 131 }
132 132
133 // Return most compact integer (i.e. possibly Smi or Mint). 133 // Return most compact integer (i.e. possibly Smi or Mint).
134 int _toValidInt() { 134 int _toValidInt() {
135 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. 135 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised.
136 var used = _used; 136 var used = _used;
137 if (used == 0) return 0; 137 if (used == 0) return 0;
138 var digits = _digits; 138 var digits = _digits;
139 if (used == 1) return _neg ? -digits[0] : digits[0]; 139 if (used == 1) return _neg ? -digits[0] : digits[0];
140 if (used > 2) return this; 140 if (used > 2) return this;
141 if (_neg) { 141 if (_neg) {
142 if (digits[1] > 0x80000000) return this; 142 if (digits[1] > 0x80000000) return this;
143 if (digits[1] == 0x80000000) { 143 if (digits[1] == 0x80000000) {
144 if (digits[0] > 0) return this; 144 if (digits[0] > 0) return this;
145 return _MIN_INT64; 145 return _MIN_INT64;
(...skipping 21 matching lines...) Expand all
167 var neg = _neg; 167 var neg = _neg;
168 if (!neg) { 168 if (!neg) {
169 return this; 169 return this;
170 } 170 }
171 return new _Bigint(!neg, _used, _digits); 171 return new _Bigint(!neg, _used, _digits);
172 } 172 }
173 173
174 // Return the bit length of digit x. 174 // Return the bit length of digit x.
175 static int _nbits(int x) { 175 static int _nbits(int x) {
176 var r = 1, t; 176 var r = 1, t;
177 if ((t = x >> 16) != 0) { x = t; r += 16; } 177 if ((t = x >> 16) != 0) {
178 if ((t = x >> 8) != 0) { x = t; r += 8; } 178 x = t;
179 if ((t = x >> 4) != 0) { x = t; r += 4; } 179 r += 16;
180 if ((t = x >> 2) != 0) { x = t; r += 2; } 180 }
181 if ((x >> 1) != 0) { r += 1; } 181 if ((t = x >> 8) != 0) {
182 x = t;
183 r += 8;
184 }
185 if ((t = x >> 4) != 0) {
186 x = t;
187 r += 4;
188 }
189 if ((t = x >> 2) != 0) {
190 x = t;
191 r += 2;
192 }
193 if ((x >> 1) != 0) {
194 r += 1;
195 }
182 return r; 196 return r;
183 } 197 }
184 198
185 // Return this << n*_DIGIT_BITS. 199 // Return this << n*_DIGIT_BITS.
186 _Bigint _dlShift(int n) { 200 _Bigint _dlShift(int n) {
187 final used = _used; 201 final used = _used;
188 if (used == 0) { 202 if (used == 0) {
189 return _ZERO; 203 return _ZERO;
190 } 204 }
191 final r_used = used + n; 205 final r_used = used + n;
192 final digits = _digits; 206 final digits = _digits;
193 final r_digits = new Uint32List(r_used + (r_used & 1)); 207 final r_digits = new Uint32List(r_used + (r_used & 1));
194 var i = used; 208 var i = used;
195 while (--i >= 0) { 209 while (--i >= 0) {
196 r_digits[i + n] = digits[i]; 210 r_digits[i + n] = digits[i];
197 } 211 }
198 return new _Bigint(_neg, r_used, r_digits); 212 return new _Bigint(_neg, r_used, r_digits);
199 } 213 }
200 214
201 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n*_DIGIT_BITS. 215 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n*_DIGIT_BITS.
202 // Return r_used. 216 // Return r_used.
203 static int _dlShiftDigits(Uint32List x_digits, int x_used, int n, 217 static int _dlShiftDigits(
204 Uint32List r_digits) { 218 Uint32List x_digits, int x_used, int n, Uint32List r_digits) {
205 if (x_used == 0) { 219 if (x_used == 0) {
206 return 0; 220 return 0;
207 } 221 }
208 if (n == 0 && identical(r_digits, x_digits)) { 222 if (n == 0 && identical(r_digits, x_digits)) {
209 return x_used; 223 return x_used;
210 } 224 }
211 final r_used = x_used + n; 225 final r_used = x_used + n;
212 assert(r_digits.length >= r_used + (r_used & 1)); 226 assert(r_digits.length >= r_used + (r_used & 1));
213 var i = x_used; 227 var i = x_used;
214 while (--i >= 0) { 228 while (--i >= 0) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 if (digits[i] != 0) { 260 if (digits[i] != 0) {
247 return r._sub(_ONE); 261 return r._sub(_ONE);
248 } 262 }
249 } 263 }
250 } 264 }
251 return r; 265 return r;
252 } 266 }
253 267
254 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n*_DIGIT_BITS. 268 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n*_DIGIT_BITS.
255 // Return r_used. 269 // Return r_used.
256 static int _drShiftDigits(Uint32List x_digits, int x_used, int n, 270 static int _drShiftDigits(
257 Uint32List r_digits) { 271 Uint32List x_digits, int x_used, int n, Uint32List r_digits) {
258 final r_used = x_used - n; 272 final r_used = x_used - n;
259 if (r_used <= 0) { 273 if (r_used <= 0) {
260 return 0; 274 return 0;
261 } 275 }
262 assert(r_digits.length >= r_used + (r_used & 1)); 276 assert(r_digits.length >= r_used + (r_used & 1));
263 for (var i = n; i < x_used; i++) { 277 for (var i = n; i < x_used; i++) {
264 r_digits[i - n] = x_digits[i]; 278 r_digits[i - n] = x_digits[i];
265 } 279 }
266 if (r_used.isOdd) { 280 if (r_used.isOdd) {
267 r_digits[r_used] = 0; 281 r_digits[r_used] = 0;
268 } 282 }
269 return r_used; 283 return r_used;
270 } 284 }
271 285
272 // r_digits[ds..x_used+ds] = x_digits[0..x_used-1] << (n % _DIGIT_BITS) 286 // r_digits[ds..x_used+ds] = x_digits[0..x_used-1] << (n % _DIGIT_BITS)
273 // where ds = ceil(n / _DIGIT_BITS) 287 // where ds = ceil(n / _DIGIT_BITS)
274 // Doesn't clear digits below ds. 288 // Doesn't clear digits below ds.
275 static void _lsh(Uint32List x_digits, int x_used, int n, 289 static void _lsh(
276 Uint32List r_digits) { 290 Uint32List x_digits, int x_used, int n, Uint32List r_digits) {
277 final ds = n ~/ _DIGIT_BITS; 291 final ds = n ~/ _DIGIT_BITS;
278 final bs = n % _DIGIT_BITS; 292 final bs = n % _DIGIT_BITS;
279 final cbs = _DIGIT_BITS - bs; 293 final cbs = _DIGIT_BITS - bs;
280 final bm = (1 << cbs) - 1; 294 final bm = (1 << cbs) - 1;
281 var c = 0; 295 var c = 0;
282 var i = x_used; 296 var i = x_used;
283 while (--i >= 0) { 297 while (--i >= 0) {
284 final d = x_digits[i]; 298 final d = x_digits[i];
285 r_digits[i + ds + 1] = (d >> cbs) | c; 299 r_digits[i + ds + 1] = (d >> cbs) | c;
286 c = (d & bm) << bs; 300 c = (d & bm) << bs;
287 } 301 }
288 r_digits[ds] = c; 302 r_digits[ds] = c;
289 } 303 }
290 304
291 // Return this << n. 305 // Return this << n.
292 _Bigint _lShift(int n) { 306 _Bigint _lShift(int n) {
293 final ds = n ~/ _DIGIT_BITS; 307 final ds = n ~/ _DIGIT_BITS;
294 final bs = n % _DIGIT_BITS; 308 final bs = n % _DIGIT_BITS;
295 if (bs == 0) { 309 if (bs == 0) {
296 return _dlShift(ds); 310 return _dlShift(ds);
297 } 311 }
298 var r_used = _used + ds + 1; 312 var r_used = _used + ds + 1;
299 var r_digits = new Uint32List(r_used + 2 - (r_used & 1)); // for 64-bit. 313 var r_digits = new Uint32List(r_used + 2 - (r_used & 1)); // for 64-bit.
300 _lsh(_digits, _used, n, r_digits); 314 _lsh(_digits, _used, n, r_digits);
301 return new _Bigint(_neg, r_used, r_digits); 315 return new _Bigint(_neg, r_used, r_digits);
302 } 316 }
303 317
304 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. 318 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n.
305 // Return r_used. 319 // Return r_used.
306 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, 320 static int _lShiftDigits(
307 Uint32List r_digits) { 321 Uint32List x_digits, int x_used, int n, Uint32List r_digits) {
308 final ds = n ~/ _DIGIT_BITS; 322 final ds = n ~/ _DIGIT_BITS;
309 final bs = n % _DIGIT_BITS; 323 final bs = n % _DIGIT_BITS;
310 if (bs == 0) { 324 if (bs == 0) {
311 return _dlShiftDigits(x_digits, x_used, ds, r_digits); 325 return _dlShiftDigits(x_digits, x_used, ds, r_digits);
312 } 326 }
313 var r_used = x_used + ds + 1; 327 var r_used = x_used + ds + 1;
314 assert(r_digits.length >= r_used + 2 - (r_used & 1)); // for 64-bit. 328 assert(r_digits.length >= r_used + 2 - (r_used & 1)); // for 64-bit.
315 _lsh(x_digits, x_used, n, r_digits); 329 _lsh(x_digits, x_used, n, r_digits);
316 var i = ds; 330 var i = ds;
317 while (--i >= 0) { 331 while (--i >= 0) {
318 r_digits[i] = 0; 332 r_digits[i] = 0;
319 } 333 }
320 if (r_digits[r_used - 1] == 0) { 334 if (r_digits[r_used - 1] == 0) {
321 r_used--; // Clamp result. 335 r_used--; // Clamp result.
322 } else if (r_used.isOdd) { 336 } else if (r_used.isOdd) {
323 r_digits[r_used] = 0; 337 r_digits[r_used] = 0;
324 } 338 }
325 return r_used; 339 return r_used;
326 } 340 }
327 341
328 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n. 342 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n.
329 static void _rsh(Uint32List x_digits, int x_used, int n, 343 static void _rsh(
330 Uint32List r_digits) { 344 Uint32List x_digits, int x_used, int n, Uint32List r_digits) {
331 final ds = n ~/ _DIGIT_BITS; 345 final ds = n ~/ _DIGIT_BITS;
332 final bs = n % _DIGIT_BITS; 346 final bs = n % _DIGIT_BITS;
333 final cbs = _DIGIT_BITS - bs; 347 final cbs = _DIGIT_BITS - bs;
334 final bm = (1 << bs) - 1; 348 final bm = (1 << bs) - 1;
335 var c = x_digits[ds] >> bs; 349 var c = x_digits[ds] >> bs;
336 final last = x_used - ds - 1; 350 final last = x_used - ds - 1;
337 for (var i = 0; i < last; i++) { 351 for (var i = 0; i < last; i++) {
338 final d = x_digits[i + ds + 1]; 352 final d = x_digits[i + ds + 1];
339 r_digits[i] = ((d & bm) << cbs) | c; 353 r_digits[i] = ((d & bm) << cbs) | c;
340 c = d >> bs; 354 c = d >> bs;
(...skipping 26 matching lines...) Expand all
367 if (digits[i] != 0) { 381 if (digits[i] != 0) {
368 return r._sub(_ONE); 382 return r._sub(_ONE);
369 } 383 }
370 } 384 }
371 } 385 }
372 return r; 386 return r;
373 } 387 }
374 388
375 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n. 389 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n.
376 // Return r_used. 390 // Return r_used.
377 static int _rShiftDigits(Uint32List x_digits, int x_used, int n, 391 static int _rShiftDigits(
378 Uint32List r_digits) { 392 Uint32List x_digits, int x_used, int n, Uint32List r_digits) {
379 final ds = n ~/ _DIGIT_BITS; 393 final ds = n ~/ _DIGIT_BITS;
380 final bs = n % _DIGIT_BITS; 394 final bs = n % _DIGIT_BITS;
381 if (bs == 0) { 395 if (bs == 0) {
382 return _drShiftDigits(x_digits, x_used, ds, r_digits); 396 return _drShiftDigits(x_digits, x_used, ds, r_digits);
383 } 397 }
384 var r_used = x_used - ds; 398 var r_used = x_used - ds;
385 if (r_used <= 0) { 399 if (r_used <= 0) {
386 return 0; 400 return 0;
387 } 401 }
388 assert(r_digits.length >= r_used + (r_used & 1)); 402 assert(r_digits.length >= r_used + (r_used & 1));
389 _rsh(x_digits, x_used, n, r_digits); 403 _rsh(x_digits, x_used, n, r_digits);
390 if (r_digits[r_used - 1] == 0) { 404 if (r_digits[r_used - 1] == 0) {
391 r_used--; // Clamp result. 405 r_used--; // Clamp result.
392 } else if (r_used.isOdd) { 406 } else if (r_used.isOdd) {
393 r_digits[r_used] = 0; 407 r_digits[r_used] = 0;
394 } 408 }
395 return r_used; 409 return r_used;
396 } 410 }
397 411
398 // Return 0 if abs(this) == abs(a). 412 // Return 0 if abs(this) == abs(a).
399 // Return a positive number if abs(this) > abs(a). 413 // Return a positive number if abs(this) > abs(a).
400 // Return a negative number if abs(this) < abs(a). 414 // Return a negative number if abs(this) < abs(a).
401 int _absCompare(_Bigint a) { 415 int _absCompare(_Bigint a) {
(...skipping 15 matching lines...) Expand all
417 var r = _absCompare(a); 431 var r = _absCompare(a);
418 return _neg ? -r : r; 432 return _neg ? -r : r;
419 } 433 }
420 return _neg ? -1 : 1; 434 return _neg ? -1 : 1;
421 } 435 }
422 436
423 // Compare digits[0..used-1] with a_digits[0..a_used-1]. 437 // Compare digits[0..used-1] with a_digits[0..a_used-1].
424 // Return 0 if equal. 438 // Return 0 if equal.
425 // Return a positive number if larger. 439 // Return a positive number if larger.
426 // Return a negative number if smaller. 440 // Return a negative number if smaller.
427 static int _compareDigits(Uint32List digits, int used, 441 static int _compareDigits(
428 Uint32List a_digits, int a_used) { 442 Uint32List digits, int used, Uint32List a_digits, int a_used) {
429 var r = used - a_used; 443 var r = used - a_used;
430 if (r == 0) { 444 if (r == 0) {
431 var i = a_used; 445 var i = a_used;
432 while (--i >= 0 && (r = digits[i] - a_digits[i]) == 0); 446 while (--i >= 0 && (r = digits[i] - a_digits[i]) == 0);
433 } 447 }
434 return r; 448 return r;
435 } 449 }
436 450
437 // r_digits[0..used] = digits[0..used-1] + a_digits[0..a_used-1]. 451 // r_digits[0..used] = digits[0..used-1] + a_digits[0..a_used-1].
438 // used >= a_used > 0. 452 // used >= a_used > 0.
439 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices. 453 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices.
440 static void _absAdd(Uint32List digits, int used, 454 static void _absAdd(Uint32List digits, int used, Uint32List a_digits,
441 Uint32List a_digits, int a_used, 455 int a_used, Uint32List r_digits) {
442 Uint32List r_digits) {
443 assert(used >= a_used && a_used > 0); 456 assert(used >= a_used && a_used > 0);
444 // Verify that digit pairs are accessible for 64-bit processing. 457 // Verify that digit pairs are accessible for 64-bit processing.
445 assert(digits.length > ((used - 1) | 1)); 458 assert(digits.length > ((used - 1) | 1));
446 assert(a_digits.length > ((a_used - 1) | 1)); 459 assert(a_digits.length > ((a_used - 1) | 1));
447 assert(r_digits.length > (used | 1)); 460 assert(r_digits.length > (used | 1));
448 var c = 0; 461 var c = 0;
449 for (var i = 0; i < a_used; i++) { 462 for (var i = 0; i < a_used; i++) {
450 c += digits[i] + a_digits[i]; 463 c += digits[i] + a_digits[i];
451 r_digits[i] = c & _DIGIT_MASK; 464 r_digits[i] = c & _DIGIT_MASK;
452 c >>= _DIGIT_BITS; 465 c >>= _DIGIT_BITS;
453 } 466 }
454 for (var i = a_used; i < used; i++) { 467 for (var i = a_used; i < used; i++) {
455 c += digits[i]; 468 c += digits[i];
456 r_digits[i] = c & _DIGIT_MASK; 469 r_digits[i] = c & _DIGIT_MASK;
457 c >>= _DIGIT_BITS; 470 c >>= _DIGIT_BITS;
458 } 471 }
459 r_digits[used] = c; 472 r_digits[used] = c;
460 } 473 }
461 474
462 // r_digits[0..used-1] = digits[0..used-1] - a_digits[0..a_used-1]. 475 // r_digits[0..used-1] = digits[0..used-1] - a_digits[0..a_used-1].
463 // used >= a_used > 0. 476 // used >= a_used > 0.
464 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices. 477 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices.
465 static void _absSub(Uint32List digits, int used, 478 static void _absSub(Uint32List digits, int used, Uint32List a_digits,
466 Uint32List a_digits, int a_used, 479 int a_used, Uint32List r_digits) {
467 Uint32List r_digits) {
468 assert(used >= a_used && a_used > 0); 480 assert(used >= a_used && a_used > 0);
469 // Verify that digit pairs are accessible for 64-bit processing. 481 // Verify that digit pairs are accessible for 64-bit processing.
470 assert(digits.length > ((used - 1) | 1)); 482 assert(digits.length > ((used - 1) | 1));
471 assert(a_digits.length > ((a_used - 1) | 1)); 483 assert(a_digits.length > ((a_used - 1) | 1));
472 assert(r_digits.length > ((used - 1) | 1)); 484 assert(r_digits.length > ((used - 1) | 1));
473 var c = 0; 485 var c = 0;
474 for (var i = 0; i < a_used; i++) { 486 for (var i = 0; i < a_used; i++) {
475 c += digits[i] - a_digits[i]; 487 c += digits[i] - a_digits[i];
476 r_digits[i] = c & _DIGIT_MASK; 488 r_digits[i] = c & _DIGIT_MASK;
477 c >>= _DIGIT_BITS; 489 c >>= _DIGIT_BITS;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 } 546 }
535 547
536 // Return abs(this) &~ abs(a) with sign set according to neg. 548 // Return abs(this) &~ abs(a) with sign set according to neg.
537 _Bigint _absAndNotSetSign(_Bigint a, bool neg) { 549 _Bigint _absAndNotSetSign(_Bigint a, bool neg) {
538 var r_used = _used; 550 var r_used = _used;
539 var digits = _digits; 551 var digits = _digits;
540 var a_digits = a._digits; 552 var a_digits = a._digits;
541 var r_digits = new Uint32List(r_used + (r_used & 1)); 553 var r_digits = new Uint32List(r_used + (r_used & 1));
542 var m = (r_used < a._used) ? r_used : a._used; 554 var m = (r_used < a._used) ? r_used : a._used;
543 for (var i = 0; i < m; i++) { 555 for (var i = 0; i < m; i++) {
544 r_digits[i] = digits[i] &~ a_digits[i]; 556 r_digits[i] = digits[i] & ~a_digits[i];
545 } 557 }
546 for (var i = m; i < r_used; i++) { 558 for (var i = m; i < r_used; i++) {
547 r_digits[i] = digits[i]; 559 r_digits[i] = digits[i];
548 } 560 }
549 return new _Bigint(neg, r_used, r_digits); 561 return new _Bigint(neg, r_used, r_digits);
550 } 562 }
551 563
552 // Return abs(this) | abs(a) with sign set according to neg. 564 // Return abs(this) | abs(a) with sign set according to neg.
553 _Bigint _absOrSetSign(_Bigint a, bool neg) { 565 _Bigint _absOrSetSign(_Bigint a, bool neg) {
554 var used = _used; 566 var used = _used;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 // Result cannot be zero if this and a are negative. 625 // Result cannot be zero if this and a are negative.
614 return t1._absOrSetSign(a1, true)._absAddSetSign(_ONE, true); 626 return t1._absOrSetSign(a1, true)._absAddSetSign(_ONE, true);
615 } 627 }
616 return _absAndSetSign(a, false); 628 return _absAndSetSign(a, false);
617 } 629 }
618 // _neg != a._neg 630 // _neg != a._neg
619 var p, n; 631 var p, n;
620 if (_neg) { 632 if (_neg) {
621 p = a; 633 p = a;
622 n = this; 634 n = this;
623 } else { // & is symmetric. 635 } else {
636 // & is symmetric.
624 p = this; 637 p = this;
625 n = a; 638 n = a;
626 } 639 }
627 // p & (-n) == p & ~(n-1) == p &~ (n-1) 640 // p & (-n) == p & ~(n-1) == p &~ (n-1)
628 _Bigint n1 = n._absSubSetSign(_ONE, false); 641 _Bigint n1 = n._absSubSetSign(_ONE, false);
629 return p._absAndNotSetSign(n1, false); 642 return p._absAndNotSetSign(n1, false);
630 } 643 }
631 644
632 // Return this &~ a. 645 // Return this &~ a.
633 _Bigint _andNot(_Bigint a) { 646 _Bigint _andNot(_Bigint a) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // Result cannot be zero if this and a are negative. 681 // Result cannot be zero if this and a are negative.
669 return t1._absAndSetSign(a1, true)._absAddSetSign(_ONE, true); 682 return t1._absAndSetSign(a1, true)._absAddSetSign(_ONE, true);
670 } 683 }
671 return _absOrSetSign(a, false); 684 return _absOrSetSign(a, false);
672 } 685 }
673 // _neg != a._neg 686 // _neg != a._neg
674 var p, n; 687 var p, n;
675 if (_neg) { 688 if (_neg) {
676 p = a; 689 p = a;
677 n = this; 690 n = this;
678 } else { // | is symmetric. 691 } else {
692 // | is symmetric.
679 p = this; 693 p = this;
680 n = a; 694 n = a;
681 } 695 }
682 // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1) 696 // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1)
683 _Bigint n1 = n._absSubSetSign(_ONE, true); 697 _Bigint n1 = n._absSubSetSign(_ONE, true);
684 // Result cannot be zero if only one of this or a is negative. 698 // Result cannot be zero if only one of this or a is negative.
685 return n1._absAndNotSetSign(p, true)._absAddSetSign(_ONE, true); 699 return n1._absAndNotSetSign(p, true)._absAddSetSign(_ONE, true);
686 } 700 }
687 701
688 // Return this ^ a. 702 // Return this ^ a.
689 _Bigint _xor(_Bigint a) { 703 _Bigint _xor(_Bigint a) {
690 if (_neg == a._neg) { 704 if (_neg == a._neg) {
691 if (_neg) { 705 if (_neg) {
692 // (-this) ^ (-a) == ~(this-1) ^ ~(a-1) == (this-1) ^ (a-1) 706 // (-this) ^ (-a) == ~(this-1) ^ ~(a-1) == (this-1) ^ (a-1)
693 _Bigint t1 = _absSubSetSign(_ONE, true); 707 _Bigint t1 = _absSubSetSign(_ONE, true);
694 _Bigint a1 = a._absSubSetSign(_ONE, true); 708 _Bigint a1 = a._absSubSetSign(_ONE, true);
695 return t1._absXorSetSign(a1, false); 709 return t1._absXorSetSign(a1, false);
696 } 710 }
697 return _absXorSetSign(a, false); 711 return _absXorSetSign(a, false);
698 } 712 }
699 // _neg != a._neg 713 // _neg != a._neg
700 var p, n; 714 var p, n;
701 if (_neg) { 715 if (_neg) {
702 p = a; 716 p = a;
703 n = this; 717 n = this;
704 } else { // ^ is symmetric. 718 } else {
719 // ^ is symmetric.
705 p = this; 720 p = this;
706 n = a; 721 n = a;
707 } 722 }
708 // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1) 723 // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1)
709 _Bigint n1 = n._absSubSetSign(_ONE, true); 724 _Bigint n1 = n._absSubSetSign(_ONE, true);
710 // Result cannot be zero if only one of this or a is negative. 725 // Result cannot be zero if only one of this or a is negative.
711 return p._absXorSetSign(n1, true)._absAddSetSign(_ONE, true); 726 return p._absXorSetSign(n1, true)._absAddSetSign(_ONE, true);
712 } 727 }
713 728
714 // Return ~this. 729 // Return ~this.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 // Multiply and accumulate. 772 // Multiply and accumulate.
758 // Input: 773 // Input:
759 // x_digits[xi]: multiplier digit x. 774 // x_digits[xi]: multiplier digit x.
760 // m_digits[i..i+n-1]: multiplicand digits. 775 // m_digits[i..i+n-1]: multiplicand digits.
761 // a_digits[j..j+n-1]: accumulator digits. 776 // a_digits[j..j+n-1]: accumulator digits.
762 // Operation: 777 // Operation:
763 // a_digits[j..j+n] += x_digits[xi]*m_digits[i..i+n-1]. 778 // a_digits[j..j+n] += x_digits[xi]*m_digits[i..i+n-1].
764 // return 1. 779 // return 1.
765 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices 780 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices
766 // and return 2. 781 // and return 2.
767 static int _mulAdd(Uint32List x_digits, int xi, 782 static int _mulAdd(Uint32List x_digits, int xi, Uint32List m_digits, int i,
768 Uint32List m_digits, int i, 783 Uint32List a_digits, int j, int n) {
769 Uint32List a_digits, int j, int n) {
770 // Verify that digit pairs are accessible for 64-bit processing. 784 // Verify that digit pairs are accessible for 64-bit processing.
771 assert(x_digits.length > (xi | 1)); 785 assert(x_digits.length > (xi | 1));
772 assert(m_digits.length > ((i + n - 1) | 1)); 786 assert(m_digits.length > ((i + n - 1) | 1));
773 assert(a_digits.length > ((j + n) | 1)); 787 assert(a_digits.length > ((j + n) | 1));
774 int x = x_digits[xi]; 788 int x = x_digits[xi];
775 if (x == 0) { 789 if (x == 0) {
776 // No-op if x is 0. 790 // No-op if x is 0.
777 return 1; 791 return 1;
778 } 792 }
779 int c = 0; 793 int c = 0;
780 int xl = x & _DIGIT2_MASK; 794 int xl = x & _DIGIT2_MASK;
781 int xh = x >> _DIGIT2_BITS; 795 int xh = x >> _DIGIT2_BITS;
782 while (--n >= 0) { 796 while (--n >= 0) {
783 int l = m_digits[i] & _DIGIT2_MASK; 797 int l = m_digits[i] & _DIGIT2_MASK;
784 int h = m_digits[i++] >> _DIGIT2_BITS; 798 int h = m_digits[i++] >> _DIGIT2_BITS;
785 int m = xh*l + h*xl; 799 int m = xh * l + h * xl;
786 l = xl*l + ((m & _DIGIT2_MASK) << _DIGIT2_BITS) + a_digits[j] + c; 800 l = xl * l + ((m & _DIGIT2_MASK) << _DIGIT2_BITS) + a_digits[j] + c;
787 c = (l >> _DIGIT_BITS) + (m >> _DIGIT2_BITS) + xh*h; 801 c = (l >> _DIGIT_BITS) + (m >> _DIGIT2_BITS) + xh * h;
788 a_digits[j++] = l & _DIGIT_MASK; 802 a_digits[j++] = l & _DIGIT_MASK;
789 } 803 }
790 while (c != 0) { 804 while (c != 0) {
791 int l = a_digits[j] + c; 805 int l = a_digits[j] + c;
792 c = l >> _DIGIT_BITS; 806 c = l >> _DIGIT_BITS;
793 a_digits[j++] = l & _DIGIT_MASK; 807 a_digits[j++] = l & _DIGIT_MASK;
794 } 808 }
795 return 1; 809 return 1;
796 } 810 }
797 811
798 // Square and accumulate. 812 // Square and accumulate.
799 // Input: 813 // Input:
800 // x_digits[i..used-1]: digits of operand being squared. 814 // x_digits[i..used-1]: digits of operand being squared.
801 // a_digits[2*i..i+used-1]: accumulator digits. 815 // a_digits[2*i..i+used-1]: accumulator digits.
802 // Operation: 816 // Operation:
803 // a_digits[2*i..i+used-1] += x_digits[i]*x_digits[i] + 817 // a_digits[2*i..i+used-1] += x_digits[i]*x_digits[i] +
804 // 2*x_digits[i]*x_digits[i+1..used-1]. 818 // 2*x_digits[i]*x_digits[i+1..used-1].
805 // return 1. 819 // return 1.
806 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices 820 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices
807 // and return 2. 821 // and return 2.
808 static int _sqrAdd(Uint32List x_digits, int i, 822 static int _sqrAdd(
809 Uint32List a_digits, int used) { 823 Uint32List x_digits, int i, Uint32List a_digits, int used) {
810 // Verify that digit pairs are accessible for 64-bit processing. 824 // Verify that digit pairs are accessible for 64-bit processing.
811 assert(x_digits.length > ((used - 1) | 1)); 825 assert(x_digits.length > ((used - 1) | 1));
812 assert(a_digits.length > ((i + used - 1) | 1)); 826 assert(a_digits.length > ((i + used - 1) | 1));
813 int x = x_digits[i]; 827 int x = x_digits[i];
814 if (x == 0) return 1; 828 if (x == 0) return 1;
815 int j = 2*i; 829 int j = 2 * i;
816 int c = 0; 830 int c = 0;
817 int xl = x & _DIGIT2_MASK; 831 int xl = x & _DIGIT2_MASK;
818 int xh = x >> _DIGIT2_BITS; 832 int xh = x >> _DIGIT2_BITS;
819 int m = 2*xh*xl; 833 int m = 2 * xh * xl;
820 int l = xl*xl + ((m & _DIGIT2_MASK) << _DIGIT2_BITS) + a_digits[j]; 834 int l = xl * xl + ((m & _DIGIT2_MASK) << _DIGIT2_BITS) + a_digits[j];
821 c = (l >> _DIGIT_BITS) + (m >> _DIGIT2_BITS) + xh*xh; 835 c = (l >> _DIGIT_BITS) + (m >> _DIGIT2_BITS) + xh * xh;
822 a_digits[j] = l & _DIGIT_MASK; 836 a_digits[j] = l & _DIGIT_MASK;
823 x <<= 1; 837 x <<= 1;
824 xl = x & _DIGIT2_MASK; 838 xl = x & _DIGIT2_MASK;
825 xh = x >> _DIGIT2_BITS; 839 xh = x >> _DIGIT2_BITS;
826 int n = used - i - 1; 840 int n = used - i - 1;
827 int k = i + 1; 841 int k = i + 1;
828 j++; 842 j++;
829 while (--n >= 0) { 843 while (--n >= 0) {
830 int l = x_digits[k] & _DIGIT2_MASK; 844 int l = x_digits[k] & _DIGIT2_MASK;
831 int h = x_digits[k++] >> _DIGIT2_BITS; 845 int h = x_digits[k++] >> _DIGIT2_BITS;
832 int m = xh*l + h*xl; 846 int m = xh * l + h * xl;
833 l = xl*l + ((m & _DIGIT2_MASK) << _DIGIT2_BITS) + a_digits[j] + c; 847 l = xl * l + ((m & _DIGIT2_MASK) << _DIGIT2_BITS) + a_digits[j] + c;
834 c = (l >> _DIGIT_BITS) + (m >> _DIGIT2_BITS) + xh*h; 848 c = (l >> _DIGIT_BITS) + (m >> _DIGIT2_BITS) + xh * h;
835 a_digits[j++] = l & _DIGIT_MASK; 849 a_digits[j++] = l & _DIGIT_MASK;
836 } 850 }
837 c += a_digits[i + used]; 851 c += a_digits[i + used];
838 if (c >= _DIGIT_BASE) { 852 if (c >= _DIGIT_BASE) {
839 a_digits[i + used] = c - _DIGIT_BASE; 853 a_digits[i + used] = c - _DIGIT_BASE;
840 a_digits[i + used + 1] = 1; 854 a_digits[i + used + 1] = 1;
841 } else { 855 } else {
842 a_digits[i + used] = c; 856 a_digits[i + used] = c;
843 } 857 }
844 return 1; 858 return 1;
(...skipping 13 matching lines...) Expand all
858 var r_digits = new Uint32List(r_used + (r_used & 1)); 872 var r_digits = new Uint32List(r_used + (r_used & 1));
859 var i = 0; 873 var i = 0;
860 while (i < a_used) { 874 while (i < a_used) {
861 i += _mulAdd(a_digits, i, digits, 0, r_digits, i, used); 875 i += _mulAdd(a_digits, i, digits, 0, r_digits, i, used);
862 } 876 }
863 return new _Bigint(_neg != a._neg, r_used, r_digits); 877 return new _Bigint(_neg != a._neg, r_used, r_digits);
864 } 878 }
865 879
866 // r_digits[0..r_used-1] = x_digits[0..x_used-1]*a_digits[0..a_used-1]. 880 // r_digits[0..r_used-1] = x_digits[0..x_used-1]*a_digits[0..a_used-1].
867 // Return r_used = x_used + a_used. 881 // Return r_used = x_used + a_used.
868 static int _mulDigits(Uint32List x_digits, int x_used, 882 static int _mulDigits(Uint32List x_digits, int x_used, Uint32List a_digits,
869 Uint32List a_digits, int a_used, 883 int a_used, Uint32List r_digits) {
870 Uint32List r_digits) {
871 var r_used = x_used + a_used; 884 var r_used = x_used + a_used;
872 var i = r_used + (r_used & 1); 885 var i = r_used + (r_used & 1);
873 assert(r_digits.length >= i); 886 assert(r_digits.length >= i);
874 while (--i >= 0) { 887 while (--i >= 0) {
875 r_digits[i] = 0; 888 r_digits[i] = 0;
876 } 889 }
877 i = 0; 890 i = 0;
878 while (i < a_used) { 891 while (i < a_used) {
879 i += _mulAdd(a_digits, i, x_digits, 0, r_digits, i, x_used); 892 i += _mulAdd(a_digits, i, x_digits, 0, r_digits, i, x_used);
880 } 893 }
881 return r_used; 894 return r_used;
882 } 895 }
883 896
884 // Return this^2. 897 // Return this^2.
885 _Bigint _sqr() { 898 _Bigint _sqr() {
886 var used = _used; 899 var used = _used;
887 if (used == 0) { 900 if (used == 0) {
888 return _ZERO; 901 return _ZERO;
889 } 902 }
890 var r_used = 2 * used; 903 var r_used = 2 * used;
891 var digits = _digits; 904 var digits = _digits;
892 var r_digits = new Uint32List(r_used); 905 var r_digits = new Uint32List(r_used);
893 // Since r_used is even, no need for a leading zero for 64-bit processing. 906 // Since r_used is even, no need for a leading zero for 64-bit processing.
894 var i = 0; 907 var i = 0;
895 while (i < used - 1) { 908 while (i < used - 1) {
896 i += _sqrAdd(digits, i, r_digits, used); 909 i += _sqrAdd(digits, i, r_digits, used);
897 } 910 }
898 // The last step is already done if digit pairs were processed above. 911 // The last step is already done if digit pairs were processed above.
899 if (i < used) { 912 if (i < used) {
900 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1); 913 _mulAdd(digits, i, digits, i, r_digits, 2 * i, 1);
901 } 914 }
902 return new _Bigint(false, r_used, r_digits); 915 return new _Bigint(false, r_used, r_digits);
903 } 916 }
904 917
905 // r_digits[0..r_used-1] = x_digits[0..x_used-1]*x_digits[0..x_used-1]. 918 // r_digits[0..r_used-1] = x_digits[0..x_used-1]*x_digits[0..x_used-1].
906 // Return r_used = 2*x_used. 919 // Return r_used = 2*x_used.
907 static int _sqrDigits(Uint32List x_digits, int x_used, Uint32List r_digits) { 920 static int _sqrDigits(Uint32List x_digits, int x_used, Uint32List r_digits) {
908 var r_used = 2 * x_used; 921 var r_used = 2 * x_used;
909 assert(r_digits.length >= r_used); 922 assert(r_digits.length >= r_used);
910 // Since r_used is even, no need for a leading zero for 64-bit processing. 923 // Since r_used is even, no need for a leading zero for 64-bit processing.
911 var i = r_used; 924 var i = r_used;
912 while (--i >= 0) { 925 while (--i >= 0) {
913 r_digits[i] = 0; 926 r_digits[i] = 0;
914 } 927 }
915 i = 0; 928 i = 0;
916 while (i < x_used - 1) { 929 while (i < x_used - 1) {
917 i += _sqrAdd(x_digits, i, r_digits, x_used); 930 i += _sqrAdd(x_digits, i, r_digits, x_used);
918 } 931 }
919 // The last step is already done if digit pairs were processed above. 932 // The last step is already done if digit pairs were processed above.
920 if (i < x_used) { 933 if (i < x_used) {
921 _mulAdd(x_digits, i, x_digits, i, r_digits, 2*i, 1); 934 _mulAdd(x_digits, i, x_digits, i, r_digits, 2 * i, 1);
922 } 935 }
923 return r_used; 936 return r_used;
924 } 937 }
925 938
926 // Indices of the arguments of _estQuotientDigit. 939 // Indices of the arguments of _estQuotientDigit.
927 // For 64-bit processing by intrinsics on 64-bit platforms, the top digit pair 940 // For 64-bit processing by intrinsics on 64-bit platforms, the top digit pair
928 // of divisor y is provided in the args array, and a 64-bit estimated quotient 941 // of divisor y is provided in the args array, and a 64-bit estimated quotient
929 // is returned. However, on 32-bit platforms, the low 32-bit digit is ignored 942 // is returned. However, on 32-bit platforms, the low 32-bit digit is ignored
930 // and only one 32-bit digit is returned as the estimated quotient. 943 // and only one 32-bit digit is returned as the estimated quotient.
931 static const int _YT_LO = 0; // Low digit of top digit pair of y, for 64-bit. 944 static const int _YT_LO = 0; // Low digit of top digit pair of y, for 64-bit.
932 static const int _YT = 1; // Top digit of divisor y. 945 static const int _YT = 1; // Top digit of divisor y.
933 static const int _QD = 2; // Estimated quotient. 946 static const int _QD = 2; // Estimated quotient.
934 static const int _QD_HI = 3; // High digit of estimated quotient, for 64-bit. 947 static const int _QD_HI = 3; // High digit of estimated quotient, for 64-bit.
935 948
936 // Operation: 949 // Operation:
937 // Estimate args[_QD] = digits[i-1..i] ~/ args[_YT] 950 // Estimate args[_QD] = digits[i-1..i] ~/ args[_YT]
938 // return 1 951 // return 1
939 // Note: Intrinsics on 64-bit platforms process a digit pair (i always odd): 952 // Note: Intrinsics on 64-bit platforms process a digit pair (i always odd):
940 // Estimate args[_QD.._QD_HI] = digits[i-3..i] ~/ args[_YT_LO.._YT] 953 // Estimate args[_QD.._QD_HI] = digits[i-3..i] ~/ args[_YT_LO.._YT]
941 // return 2 954 // return 2
942 static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) { 955 static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
943 // Verify that digit pairs are accessible for 64-bit processing. 956 // Verify that digit pairs are accessible for 64-bit processing.
944 assert(digits.length >= 4); 957 assert(digits.length >= 4);
945 if (digits[i] == args[_YT]) { 958 if (digits[i] == args[_YT]) {
946 args[_QD] = _DIGIT_MASK; 959 args[_QD] = _DIGIT_MASK;
947 } else { 960 } else {
948 // Chop off one bit, since a Mint cannot hold 2 DIGITs. 961 // Chop off one bit, since a Mint cannot hold 2 DIGITs.
949 var qd = ((digits[i] << (_DIGIT_BITS - 1)) | (digits[i - 1] >> 1)) 962 var qd = ((digits[i] << (_DIGIT_BITS - 1)) | (digits[i - 1] >> 1)) ~/
950 ~/ (args[_YT] >> 1); 963 (args[_YT] >> 1);
951 if (qd > _DIGIT_MASK) { 964 if (qd > _DIGIT_MASK) {
952 args[_QD] = _DIGIT_MASK; 965 args[_QD] = _DIGIT_MASK;
953 } else { 966 } else {
954 args[_QD] = qd; 967 args[_QD] = qd;
955 } 968 }
956 } 969 }
957 return 1; 970 return 1;
958 } 971 }
959 972
960 // Return trunc(this / a), a != 0. 973 // Return trunc(this / a), a != 0.
961 _Bigint _div(_Bigint a) { 974 _Bigint _div(_Bigint a) {
962 assert(a._used > 0); 975 assert(a._used > 0);
963 if (_used < a._used) { 976 if (_used < a._used) {
964 return _ZERO; 977 return _ZERO;
965 } 978 }
966 _divRem(a); 979 _divRem(a);
967 // Return quotient, i.e. 980 // Return quotient, i.e.
968 // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign. 981 // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
969 var lastQuo_used = _lastQuoRem_used - _lastRem_used; 982 var lastQuo_used = _lastQuoRem_used - _lastRem_used;
970 var quo_digits = _cloneDigits(_lastQuoRem_digits, 983 var quo_digits = _cloneDigits(
971 _lastRem_used, 984 _lastQuoRem_digits, _lastRem_used, _lastQuoRem_used, lastQuo_used);
972 _lastQuoRem_used,
973 lastQuo_used);
974 var quo = new _Bigint(false, lastQuo_used, quo_digits); 985 var quo = new _Bigint(false, lastQuo_used, quo_digits);
975 if ((_neg != a._neg) && (quo._used > 0)) { 986 if ((_neg != a._neg) && (quo._used > 0)) {
976 quo = quo._negate(); 987 quo = quo._negate();
977 } 988 }
978 return quo; 989 return quo;
979 } 990 }
980 991
981 // Return this - a * trunc(this / a), a != 0. 992 // Return this - a * trunc(this / a), a != 0.
982 _Bigint _rem(_Bigint a) { 993 _Bigint _rem(_Bigint a) {
983 assert(a._used > 0); 994 assert(a._used > 0);
984 if (_used < a._used) { 995 if (_used < a._used) {
985 return this; 996 return this;
986 } 997 }
987 _divRem(a); 998 _divRem(a);
988 // Return remainder, i.e. 999 // Return remainder, i.e.
989 // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign. 1000 // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
990 var rem_digits = _cloneDigits(_lastQuoRem_digits, 1001 var rem_digits =
991 0, 1002 _cloneDigits(_lastQuoRem_digits, 0, _lastRem_used, _lastRem_used);
992 _lastRem_used,
993 _lastRem_used);
994 var rem = new _Bigint(false, _lastRem_used, rem_digits); 1003 var rem = new _Bigint(false, _lastRem_used, rem_digits);
995 if (_lastRem_nsh > 0) { 1004 if (_lastRem_nsh > 0) {
996 rem = rem._rShift(_lastRem_nsh); // Denormalize remainder. 1005 rem = rem._rShift(_lastRem_nsh); // Denormalize remainder.
997 } 1006 }
998 if (_neg && (rem._used > 0)) { 1007 if (_neg && (rem._used > 0)) {
999 rem = rem._negate(); 1008 rem = rem._negate();
1000 } 1009 }
1001 return rem; 1010 return rem;
1002 } 1011 }
1003 1012
1004 // Cache concatenated positive quotient and normalized positive remainder. 1013 // Cache concatenated positive quotient and normalized positive remainder.
1005 void _divRem(_Bigint a) { 1014 void _divRem(_Bigint a) {
1006 // Check if result is already cached (identical on Bigint is too expensive). 1015 // Check if result is already cached (identical on Bigint is too expensive).
1007 if ((this._used == _lastDividend_used) && 1016 if ((this._used == _lastDividend_used) &&
1008 (a._used == _lastDivisor_used) && 1017 (a._used == _lastDivisor_used) &&
1009 identical(this._digits, _lastDividend_digits) && 1018 identical(this._digits, _lastDividend_digits) &&
1010 identical(a._digits, _lastDivisor_digits)) { 1019 identical(a._digits, _lastDivisor_digits)) {
1011 return; 1020 return;
1012 } 1021 }
1013 var nsh = _DIGIT_BITS - _nbits(a._digits[a._used - 1]); 1022 var nsh = _DIGIT_BITS - _nbits(a._digits[a._used - 1]);
1014 // For 64-bit processing, make sure y has an even number of digits. 1023 // For 64-bit processing, make sure y has an even number of digits.
1015 if (a._used.isOdd) { 1024 if (a._used.isOdd) {
1016 nsh += _DIGIT_BITS; 1025 nsh += _DIGIT_BITS;
1017 } 1026 }
1018 // Concatenated positive quotient and normalized positive remainder. 1027 // Concatenated positive quotient and normalized positive remainder.
1019 var r_digits; 1028 var r_digits;
1020 var r_used; 1029 var r_used;
1021 // Normalized positive divisor. 1030 // Normalized positive divisor.
1022 var y_digits; 1031 var y_digits;
1023 var y_used; 1032 var y_used;
1024 if (nsh > 0) { 1033 if (nsh > 0) {
1025 y_digits = new Uint32List(a._used + 5); // +5 for norm. and 64-bit. 1034 y_digits = new Uint32List(a._used + 5); // +5 for norm. and 64-bit.
1026 y_used = _lShiftDigits(a._digits, a._used, nsh, y_digits); 1035 y_used = _lShiftDigits(a._digits, a._used, nsh, y_digits);
1027 r_digits = new Uint32List(_used + 5); // +5 for normalization and 64-bit. 1036 r_digits = new Uint32List(_used + 5); // +5 for normalization and 64-bit.
1028 r_used = _lShiftDigits(_digits, _used, nsh, r_digits); 1037 r_used = _lShiftDigits(_digits, _used, nsh, r_digits);
1029 } else { 1038 } else {
1030 y_digits = a._digits; 1039 y_digits = a._digits;
1031 y_used = a._used; 1040 y_used = a._used;
1032 r_digits = _cloneDigits(_digits, 0, _used, _used + 2); 1041 r_digits = _cloneDigits(_digits, 0, _used, _used + 2);
1033 r_used = _used; 1042 r_used = _used;
1034 } 1043 }
1035 Uint32List yt_qd = new Uint32List(4); 1044 Uint32List yt_qd = new Uint32List(4);
1036 yt_qd[_YT_LO] = y_digits[y_used - 2]; 1045 yt_qd[_YT_LO] = y_digits[y_used - 2];
1037 yt_qd[_YT] = y_digits[y_used - 1]; 1046 yt_qd[_YT] = y_digits[y_used - 1];
1038 // For 64-bit processing, make sure y_used, i, and j are even. 1047 // For 64-bit processing, make sure y_used, i, and j are even.
1039 assert(y_used.isEven); 1048 assert(y_used.isEven);
1040 var i = r_used + (r_used & 1); 1049 var i = r_used + (r_used & 1);
1041 var j = i - y_used; 1050 var j = i - y_used;
1042 // t_digits is a temporary array of i digits. 1051 // t_digits is a temporary array of i digits.
1043 var t_digits = new Uint32List(i); 1052 var t_digits = new Uint32List(i);
1044 var t_used = _dlShiftDigits(y_digits, y_used, j, t_digits); 1053 var t_used = _dlShiftDigits(y_digits, y_used, j, t_digits);
1045 // Explicit first division step in case normalized dividend is larger or 1054 // Explicit first division step in case normalized dividend is larger or
1046 // equal to shifted normalized divisor. 1055 // equal to shifted normalized divisor.
1047 if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) { 1056 if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) {
1048 assert(i == r_used); 1057 assert(i == r_used);
1049 r_digits[r_used++] = 1; // Quotient = 1. 1058 r_digits[r_used++] = 1; // Quotient = 1.
1050 // Subtract divisor from remainder. 1059 // Subtract divisor from remainder.
1051 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1060 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1052 } else { 1061 } else {
1053 // Account for possible carry in _mulAdd step. 1062 // Account for possible carry in _mulAdd step.
1054 r_digits[r_used++] = 0; 1063 r_digits[r_used++] = 0;
1055 } 1064 }
1056 r_digits[r_used] = 0; // Leading zero for 64-bit processing. 1065 r_digits[r_used] = 0; // Leading zero for 64-bit processing.
1057 // Negate y so we can later use _mulAdd instead of non-existent _mulSub. 1066 // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
1058 var ny_digits = new Uint32List(y_used + 2); 1067 var ny_digits = new Uint32List(y_used + 2);
1059 ny_digits[y_used] = 1; 1068 ny_digits[y_used] = 1;
1060 _absSub(ny_digits, y_used + 1, y_digits, y_used, ny_digits); 1069 _absSub(ny_digits, y_used + 1, y_digits, y_used, ny_digits);
1061 // ny_digits is read-only and has y_used digits (possibly including several 1070 // ny_digits is read-only and has y_used digits (possibly including several
1062 // leading zeros) plus a leading zero for 64-bit processing. 1071 // leading zeros) plus a leading zero for 64-bit processing.
1063 // r_digits is modified during iteration. 1072 // r_digits is modified during iteration.
1064 // r_digits[0..y_used-1] is the current remainder. 1073 // r_digits[0..y_used-1] is the current remainder.
1065 // r_digits[y_used..r_used-1] is the current quotient. 1074 // r_digits[y_used..r_used-1] is the current quotient.
1066 --i; 1075 --i;
1067 while (j > 0) { 1076 while (j > 0) {
1068 var d0 = _estQuotientDigit(yt_qd, r_digits, i); 1077 var d0 = _estQuotientDigit(yt_qd, r_digits, i);
1069 j -= d0; 1078 j -= d0;
1070 var d1 = _mulAdd(yt_qd, _QD, ny_digits, 0, r_digits, j, y_used); 1079 var d1 = _mulAdd(yt_qd, _QD, ny_digits, 0, r_digits, j, y_used);
1071 // _estQuotientDigit and _mulAdd must agree on the number of digits to 1080 // _estQuotientDigit and _mulAdd must agree on the number of digits to
1072 // process. 1081 // process.
1073 assert(d0 == d1); 1082 assert(d0 == d1);
1074 if (d0 == 1) { 1083 if (d0 == 1) {
1075 if (r_digits[i] < yt_qd[_QD]) { 1084 if (r_digits[i] < yt_qd[_QD]) {
1076 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits); 1085 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits);
1077 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1086 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1078 while (r_digits[i] < --yt_qd[_QD]) { 1087 while (r_digits[i] < --yt_qd[_QD]) {
1079 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1088 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1080 } 1089 }
1081 } 1090 }
1082 } else { 1091 } else {
1083 assert(d0 == 2); 1092 assert(d0 == 2);
1084 assert(r_digits[i] <= yt_qd[_QD_HI]); 1093 assert(r_digits[i] <= yt_qd[_QD_HI]);
1085 if ((r_digits[i] < yt_qd[_QD_HI]) || (r_digits[i-1] < yt_qd[_QD])) { 1094 if ((r_digits[i] < yt_qd[_QD_HI]) || (r_digits[i - 1] < yt_qd[_QD])) {
1086 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits); 1095 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits);
1087 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1096 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1088 if (yt_qd[_QD] == 0) { 1097 if (yt_qd[_QD] == 0) {
1089 --yt_qd[_QD_HI]; 1098 --yt_qd[_QD_HI];
1090 } 1099 }
1091 --yt_qd[_QD]; 1100 --yt_qd[_QD];
1092 assert(r_digits[i] <= yt_qd[_QD_HI]); 1101 assert(r_digits[i] <= yt_qd[_QD_HI]);
1093 while ((r_digits[i] < yt_qd[_QD_HI]) || 1102 while (
1094 (r_digits[i-1] < yt_qd[_QD])) { 1103 (r_digits[i] < yt_qd[_QD_HI]) || (r_digits[i - 1] < yt_qd[_QD])) {
1095 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1104 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1096 if (yt_qd[_QD] == 0) { 1105 if (yt_qd[_QD] == 0) {
1097 --yt_qd[_QD_HI]; 1106 --yt_qd[_QD_HI];
1098 } 1107 }
1099 --yt_qd[_QD]; 1108 --yt_qd[_QD];
1100 assert(r_digits[i] <= yt_qd[_QD_HI]); 1109 assert(r_digits[i] <= yt_qd[_QD_HI]);
1101 } 1110 }
1102 } 1111 }
1103 } 1112 }
1104 i -= d0; 1113 i -= d0;
(...skipping 15 matching lines...) Expand all
1120 // y_digits[0..y_used-1]: normalized positive divisor. 1129 // y_digits[0..y_used-1]: normalized positive divisor.
1121 // ny_digits[0..y_used-1]: negated y_digits. 1130 // ny_digits[0..y_used-1]: negated y_digits.
1122 // nsh: normalization shift amount. 1131 // nsh: normalization shift amount.
1123 // yt_qd: top y digit(s) and place holder for estimated quotient digit(s). 1132 // yt_qd: top y digit(s) and place holder for estimated quotient digit(s).
1124 // t_digits: temp array of 2*y_used digits. 1133 // t_digits: temp array of 2*y_used digits.
1125 // r_digits: result digits array large enough to temporarily hold 1134 // r_digits: result digits array large enough to temporarily hold
1126 // concatenated quotient and normalized remainder. 1135 // concatenated quotient and normalized remainder.
1127 // Output: 1136 // Output:
1128 // r_digits[0..r_used-1]: positive remainder. 1137 // r_digits[0..r_used-1]: positive remainder.
1129 // Returns r_used. 1138 // Returns r_used.
1130 static int _remDigits(Uint32List x_digits, int x_used, 1139 static int _remDigits(
1131 Uint32List y_digits, int y_used, Uint32List ny_digits, 1140 Uint32List x_digits,
1132 int nsh, 1141 int x_used,
1133 Uint32List yt_qd, 1142 Uint32List y_digits,
1134 Uint32List t_digits, 1143 int y_used,
1135 Uint32List r_digits) { 1144 Uint32List ny_digits,
1145 int nsh,
1146 Uint32List yt_qd,
1147 Uint32List t_digits,
1148 Uint32List r_digits) {
1136 // Initialize r_digits to normalized positive dividend. 1149 // Initialize r_digits to normalized positive dividend.
1137 var r_used = _lShiftDigits(x_digits, x_used, nsh, r_digits); 1150 var r_used = _lShiftDigits(x_digits, x_used, nsh, r_digits);
1138 // For 64-bit processing, make sure y_used, i, and j are even. 1151 // For 64-bit processing, make sure y_used, i, and j are even.
1139 assert(y_used.isEven); 1152 assert(y_used.isEven);
1140 var i = r_used + (r_used & 1); 1153 var i = r_used + (r_used & 1);
1141 var j = i - y_used; 1154 var j = i - y_used;
1142 var t_used = _dlShiftDigits(y_digits, y_used, j, t_digits); 1155 var t_used = _dlShiftDigits(y_digits, y_used, j, t_digits);
1143 // Explicit first division step in case normalized dividend is larger or 1156 // Explicit first division step in case normalized dividend is larger or
1144 // equal to shifted normalized divisor. 1157 // equal to shifted normalized divisor.
1145 if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) { 1158 if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) {
1146 assert(i == r_used); 1159 assert(i == r_used);
1147 r_digits[r_used++] = 1; // Quotient = 1. 1160 r_digits[r_used++] = 1; // Quotient = 1.
1148 // Subtract divisor from remainder. 1161 // Subtract divisor from remainder.
1149 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1162 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1150 } else { 1163 } else {
1151 // Account for possible carry in _mulAdd step. 1164 // Account for possible carry in _mulAdd step.
1152 r_digits[r_used++] = 0; 1165 r_digits[r_used++] = 0;
1153 } 1166 }
1154 r_digits[r_used] = 0; // Leading zero for 64-bit processing. 1167 r_digits[r_used] = 0; // Leading zero for 64-bit processing.
1155 // Negated y_digits passed in ny_digits allow the use of _mulAdd instead of 1168 // Negated y_digits passed in ny_digits allow the use of _mulAdd instead of
1156 // unimplemented _mulSub. 1169 // unimplemented _mulSub.
1157 // ny_digits is read-only and has y_used digits (possibly including several 1170 // ny_digits is read-only and has y_used digits (possibly including several
1158 // leading zeros) plus a leading zero for 64-bit processing. 1171 // leading zeros) plus a leading zero for 64-bit processing.
1159 // r_digits is modified during iteration. 1172 // r_digits is modified during iteration.
1160 // r_digits[0..y_used-1] is the current remainder. 1173 // r_digits[0..y_used-1] is the current remainder.
1161 // r_digits[y_used..r_used-1] is the current quotient. 1174 // r_digits[y_used..r_used-1] is the current quotient.
1162 --i; 1175 --i;
1163 while (j > 0) { 1176 while (j > 0) {
1164 var d0 = _estQuotientDigit(yt_qd, r_digits, i); 1177 var d0 = _estQuotientDigit(yt_qd, r_digits, i);
1165 j -= d0; 1178 j -= d0;
1166 var d1 = _mulAdd(yt_qd, _QD, ny_digits, 0, r_digits, j, y_used); 1179 var d1 = _mulAdd(yt_qd, _QD, ny_digits, 0, r_digits, j, y_used);
1167 // _estQuotientDigit and _mulAdd must agree on the number of digits to 1180 // _estQuotientDigit and _mulAdd must agree on the number of digits to
1168 // process. 1181 // process.
1169 assert(d0 == d1); 1182 assert(d0 == d1);
1170 if (d0 == 1) { 1183 if (d0 == 1) {
1171 if (r_digits[i] < yt_qd[_QD]) { 1184 if (r_digits[i] < yt_qd[_QD]) {
1172 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits); 1185 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits);
1173 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1186 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1174 while (r_digits[i] < --yt_qd[_QD]) { 1187 while (r_digits[i] < --yt_qd[_QD]) {
1175 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1188 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1176 } 1189 }
1177 } 1190 }
1178 } else { 1191 } else {
1179 assert(d0 == 2); 1192 assert(d0 == 2);
1180 assert(r_digits[i] <= yt_qd[_QD_HI]); 1193 assert(r_digits[i] <= yt_qd[_QD_HI]);
1181 if ((r_digits[i] < yt_qd[_QD_HI]) || (r_digits[i-1] < yt_qd[_QD])) { 1194 if ((r_digits[i] < yt_qd[_QD_HI]) || (r_digits[i - 1] < yt_qd[_QD])) {
1182 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits); 1195 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits);
1183 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1196 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1184 if (yt_qd[_QD] == 0) { 1197 if (yt_qd[_QD] == 0) {
1185 --yt_qd[_QD_HI]; 1198 --yt_qd[_QD_HI];
1186 } 1199 }
1187 --yt_qd[_QD]; 1200 --yt_qd[_QD];
1188 assert(r_digits[i] <= yt_qd[_QD_HI]); 1201 assert(r_digits[i] <= yt_qd[_QD_HI]);
1189 while ((r_digits[i] < yt_qd[_QD_HI]) || 1202 while (
1190 (r_digits[i-1] < yt_qd[_QD])) { 1203 (r_digits[i] < yt_qd[_QD_HI]) || (r_digits[i - 1] < yt_qd[_QD])) {
1191 _absSub(r_digits, r_used, t_digits, t_used, r_digits); 1204 _absSub(r_digits, r_used, t_digits, t_used, r_digits);
1192 if (yt_qd[_QD] == 0) { 1205 if (yt_qd[_QD] == 0) {
1193 --yt_qd[_QD_HI]; 1206 --yt_qd[_QD_HI];
1194 } 1207 }
1195 --yt_qd[_QD]; 1208 --yt_qd[_QD];
1196 assert(r_digits[i] <= yt_qd[_QD_HI]); 1209 assert(r_digits[i] <= yt_qd[_QD_HI]);
1197 } 1210 }
1198 } 1211 }
1199 } 1212 }
1200 i -= d0; 1213 i -= d0;
(...skipping 10 matching lines...) Expand all
1211 int get hashCode => this; 1224 int get hashCode => this;
1212 int get _identityHashCode => this; 1225 int get _identityHashCode => this;
1213 1226
1214 int operator ~() { 1227 int operator ~() {
1215 return _not()._toValidInt(); 1228 return _not()._toValidInt();
1216 } 1229 }
1217 1230
1218 int get bitLength { 1231 int get bitLength {
1219 if (_used == 0) return 0; 1232 if (_used == 0) return 0;
1220 if (_neg) return (~this).bitLength; 1233 if (_neg) return (~this).bitLength;
1221 return _DIGIT_BITS*(_used - 1) + _nbits(_digits[_used - 1]); 1234 return _DIGIT_BITS * (_used - 1) + _nbits(_digits[_used - 1]);
1222 } 1235 }
1223 1236
1224 // This method must support smi._toBigint()._shrFromInt(int). 1237 // This method must support smi._toBigint()._shrFromInt(int).
1225 int _shrFromInt(int other) { 1238 int _shrFromInt(int other) {
1226 if (_used == 0) return other; // Shift amount is zero. 1239 if (_used == 0) return other; // Shift amount is zero.
1227 if (_neg) throw new RangeError.range(this, 0, null); 1240 if (_neg) throw new RangeError.range(this, 0, null);
1228 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. 1241 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised.
1229 var shift; 1242 var shift;
1230 if ((_used > 2) || ((_used == 2) && (_digits[1] > 0x10000000))) { 1243 if ((_used > 2) || ((_used == 2) && (_digits[1] > 0x10000000))) {
1231 if (other < 0) { 1244 if (other < 0) {
1232 return -1; 1245 return -1;
1233 } else { 1246 } else {
1234 return 0; 1247 return 0;
1235 } 1248 }
1236 } else { 1249 } else {
1237 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; 1250 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0];
1238 } 1251 }
1239 return other._toBigint()._rShift(shift)._toValidInt(); 1252 return other._toBigint()._rShift(shift)._toValidInt();
1240 } 1253 }
1241 1254
1242 // This method must support smi._toBigint()._shlFromInt(int). 1255 // This method must support smi._toBigint()._shlFromInt(int).
1243 // An out of memory exception is thrown if the result cannot be allocated. 1256 // An out of memory exception is thrown if the result cannot be allocated.
1244 int _shlFromInt(int other) { 1257 int _shlFromInt(int other) {
1245 if (_used == 0) return other; // Shift amount is zero. 1258 if (_used == 0) return other; // Shift amount is zero.
1246 if (_neg) throw new RangeError.range(this, 0, null); 1259 if (_neg) throw new RangeError.range(this, 0, null);
1247 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. 1260 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised.
1248 var shift; 1261 var shift;
1249 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) { 1262 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) {
1250 if (other == 0) return 0; // Shifted value is zero. 1263 if (other == 0) return 0; // Shifted value is zero.
1251 throw new OutOfMemoryError(); 1264 throw new OutOfMemoryError();
1252 } else { 1265 } else {
1253 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; 1266 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0];
1254 } 1267 }
1255 return other._toBigint()._lShift(shift)._toValidInt(); 1268 return other._toBigint()._lShift(shift)._toValidInt();
1256 } 1269 }
1257 1270
1258 // Overriden operators and methods. 1271 // Overriden operators and methods.
1259 1272
1260 // The following operators override operators of _IntegerImplementation for 1273 // The following operators override operators of _IntegerImplementation for
1261 // efficiency, but are not necessary for correctness. They shortcut native 1274 // efficiency, but are not necessary for correctness. They shortcut native
1262 // calls that would return null because the receiver is _Bigint. 1275 // calls that would return null because the receiver is _Bigint.
1263 num operator +(num other) { 1276 num operator +(num other) {
1264 return other._toBigintOrDouble()._addFromInteger(this); 1277 return other._toBigintOrDouble()._addFromInteger(this);
1265 } 1278 }
1279
1266 num operator -(num other) { 1280 num operator -(num other) {
1267 return other._toBigintOrDouble()._subFromInteger(this); 1281 return other._toBigintOrDouble()._subFromInteger(this);
1268 } 1282 }
1283
1269 num operator *(num other) { 1284 num operator *(num other) {
1270 return other._toBigintOrDouble()._mulFromInteger(this); 1285 return other._toBigintOrDouble()._mulFromInteger(this);
1271 } 1286 }
1287
1272 num operator ~/(num other) { 1288 num operator ~/(num other) {
1273 return other._toBigintOrDouble()._truncDivFromInteger(this); 1289 return other._toBigintOrDouble()._truncDivFromInteger(this);
1274 } 1290 }
1291
1275 num operator %(num other) { 1292 num operator %(num other) {
1276 return other._toBigintOrDouble()._moduloFromInteger(this); 1293 return other._toBigintOrDouble()._moduloFromInteger(this);
1277 } 1294 }
1295
1278 int operator &(int other) { 1296 int operator &(int other) {
1279 return other._toBigintOrDouble()._bitAndFromInteger(this); 1297 return other._toBigintOrDouble()._bitAndFromInteger(this);
1280 } 1298 }
1299
1281 int operator |(int other) { 1300 int operator |(int other) {
1282 return other._toBigintOrDouble()._bitOrFromInteger(this); 1301 return other._toBigintOrDouble()._bitOrFromInteger(this);
1283 } 1302 }
1303
1284 int operator ^(int other) { 1304 int operator ^(int other) {
1285 return other._toBigintOrDouble()._bitXorFromInteger(this); 1305 return other._toBigintOrDouble()._bitXorFromInteger(this);
1286 } 1306 }
1307
1287 int operator >>(int other) { 1308 int operator >>(int other) {
1288 return other._toBigintOrDouble()._shrFromInt(this); 1309 return other._toBigintOrDouble()._shrFromInt(this);
1289 } 1310 }
1311
1290 int operator <<(int other) { 1312 int operator <<(int other) {
1291 return other._toBigintOrDouble()._shlFromInt(this); 1313 return other._toBigintOrDouble()._shlFromInt(this);
1292 } 1314 }
1293 // End of operator shortcuts. 1315 // End of operator shortcuts.
1294 1316
1295 int operator -() { 1317 int operator -() {
1296 return _negate()._toValidInt(); 1318 return _negate()._toValidInt();
1297 } 1319 }
1298 1320
1299 int get sign { 1321 int get sign {
1300 return (_used == 0) ? 0 : _neg ? -1 : 1; 1322 return (_used == 0) ? 0 : _neg ? -1 : 1;
1301 } 1323 }
1302 1324
1303 bool get isEven => _used == 0 || (_digits[0] & 1) == 0; 1325 bool get isEven => _used == 0 || (_digits[0] & 1) == 0;
1304 bool get isNegative => _neg; 1326 bool get isNegative => _neg;
1305 1327
1306 String _toPow2String(int radix) { 1328 String _toPow2String(int radix) {
1307 if (_used == 0) return "0"; 1329 if (_used == 0) return "0";
1308 assert(radix & (radix - 1) == 0); 1330 assert(radix & (radix - 1) == 0);
1309 final bitsPerChar = radix.bitLength - 1; 1331 final bitsPerChar = radix.bitLength - 1;
1310 final firstcx = _neg ? 1 : 0; // Index of first char in str after the sign. 1332 final firstcx = _neg ? 1 : 0; // Index of first char in str after the sign.
1311 final lastdx = _used - 1; // Index of last digit in bigint. 1333 final lastdx = _used - 1; // Index of last digit in bigint.
1312 final bitLength = lastdx*_DIGIT_BITS + _nbits(_digits[lastdx]); 1334 final bitLength = lastdx * _DIGIT_BITS + _nbits(_digits[lastdx]);
1313 // Index of char in str. Initialize with str length. 1335 // Index of char in str. Initialize with str length.
1314 var cx = firstcx + (bitLength + bitsPerChar - 1) ~/ bitsPerChar; 1336 var cx = firstcx + (bitLength + bitsPerChar - 1) ~/ bitsPerChar;
1315 _OneByteString str = _OneByteString._allocate(cx); 1337 _OneByteString str = _OneByteString._allocate(cx);
1316 str._setAt(0, 0x2d); // '-'. Is overwritten if not negative. 1338 str._setAt(0, 0x2d); // '-'. Is overwritten if not negative.
1317 final mask = radix - 1; 1339 final mask = radix - 1;
1318 var dx = 0; // Digit index in bigint. 1340 var dx = 0; // Digit index in bigint.
1319 var bx = 0; // Bit index in bigint digit. 1341 var bx = 0; // Bit index in bigint digit.
1320 do { 1342 do {
1321 var ch; 1343 var ch;
1322 if (bx > (_DIGIT_BITS - bitsPerChar)) { 1344 if (bx > (_DIGIT_BITS - bitsPerChar)) {
1323 ch = _digits[dx++] >> bx; 1345 ch = _digits[dx++] >> bx;
1324 bx += bitsPerChar - _DIGIT_BITS; 1346 bx += bitsPerChar - _DIGIT_BITS;
1325 if (dx <= lastdx) { 1347 if (dx <= lastdx) {
1326 ch |= (_digits[dx] & ((1 << bx) - 1)) << (bitsPerChar - bx); 1348 ch |= (_digits[dx] & ((1 << bx) - 1)) << (bitsPerChar - bx);
1327 } 1349 }
1328 } else { 1350 } else {
1329 ch = (_digits[dx] >> bx) & mask; 1351 ch = (_digits[dx] >> bx) & mask;
1330 bx += bitsPerChar; 1352 bx += bitsPerChar;
1331 if (bx >= _DIGIT_BITS) { 1353 if (bx >= _DIGIT_BITS) {
1332 bx -= _DIGIT_BITS; 1354 bx -= _DIGIT_BITS;
1333 dx++; 1355 dx++;
1334 } 1356 }
1335 } 1357 }
1336 str._setAt(--cx, _IntegerImplementation._digits.codeUnitAt(ch)); 1358 str._setAt(--cx, _IntegerImplementation._digits.codeUnitAt(ch));
1337 } while (cx > firstcx); 1359 } while (cx > firstcx);
1338 return str; 1360 return str;
1339 } 1361 }
1340 1362
1341 int _bitAndFromSmi(int other) => _bitAndFromInteger(other); 1363 int _bitAndFromSmi(int other) => _bitAndFromInteger(other);
1342 1364
1343 int _bitAndFromInteger(int other) { 1365 int _bitAndFromInteger(int other) {
1344 return other._toBigint()._and(this)._toValidInt(); 1366 return other._toBigint()._and(this)._toValidInt();
1345 } 1367 }
1368
1346 int _bitOrFromInteger(int other) { 1369 int _bitOrFromInteger(int other) {
1347 return other._toBigint()._or(this)._toValidInt(); 1370 return other._toBigint()._or(this)._toValidInt();
1348 } 1371 }
1372
1349 int _bitXorFromInteger(int other) { 1373 int _bitXorFromInteger(int other) {
1350 return other._toBigint()._xor(this)._toValidInt(); 1374 return other._toBigint()._xor(this)._toValidInt();
1351 } 1375 }
1376
1352 int _addFromInteger(int other) { 1377 int _addFromInteger(int other) {
1353 return other._toBigint()._add(this)._toValidInt(); 1378 return other._toBigint()._add(this)._toValidInt();
1354 } 1379 }
1380
1355 int _subFromInteger(int other) { 1381 int _subFromInteger(int other) {
1356 return other._toBigint()._sub(this)._toValidInt(); 1382 return other._toBigint()._sub(this)._toValidInt();
1357 } 1383 }
1384
1358 int _mulFromInteger(int other) { 1385 int _mulFromInteger(int other) {
1359 return other._toBigint()._mul(this)._toValidInt(); 1386 return other._toBigint()._mul(this)._toValidInt();
1360 } 1387 }
1388
1361 int _truncDivFromInteger(int other) { 1389 int _truncDivFromInteger(int other) {
1362 if (_used == 0) { 1390 if (_used == 0) {
1363 throw const IntegerDivisionByZeroException(); 1391 throw const IntegerDivisionByZeroException();
1364 } 1392 }
1365 return other._toBigint()._div(this)._toValidInt(); 1393 return other._toBigint()._div(this)._toValidInt();
1366 } 1394 }
1395
1367 int _moduloFromInteger(int other) { 1396 int _moduloFromInteger(int other) {
1368 if (_used == 0) { 1397 if (_used == 0) {
1369 throw const IntegerDivisionByZeroException(); 1398 throw const IntegerDivisionByZeroException();
1370 } 1399 }
1371 _Bigint result = other._toBigint()._rem(this); 1400 _Bigint result = other._toBigint()._rem(this);
1372 if (result._neg) { 1401 if (result._neg) {
1373 if (_neg) { 1402 if (_neg) {
1374 result = result._sub(this); 1403 result = result._sub(this);
1375 } else { 1404 } else {
1376 result = result._add(this); 1405 result = result._add(this);
1377 } 1406 }
1378 } 1407 }
1379 return result._toValidInt(); 1408 return result._toValidInt();
1380 } 1409 }
1410
1381 int _remainderFromInteger(int other) { 1411 int _remainderFromInteger(int other) {
1382 if (_used == 0) { 1412 if (_used == 0) {
1383 throw const IntegerDivisionByZeroException(); 1413 throw const IntegerDivisionByZeroException();
1384 } 1414 }
1385 return other._toBigint()._rem(this)._toValidInt(); 1415 return other._toBigint()._rem(this)._toValidInt();
1386 } 1416 }
1417
1387 bool _greaterThanFromInteger(int other) { 1418 bool _greaterThanFromInteger(int other) {
1388 return other._toBigint()._compare(this) > 0; 1419 return other._toBigint()._compare(this) > 0;
1389 } 1420 }
1421
1390 bool _equalToInteger(int other) { 1422 bool _equalToInteger(int other) {
1391 return other._toBigint()._compare(this) == 0; 1423 return other._toBigint()._compare(this) == 0;
1392 } 1424 }
1393 1425
1394 // Returns pow(this, e) % m, with e >= 0, m > 0. 1426 // Returns pow(this, e) % m, with e >= 0, m > 0.
1395 int modPow(int e, int m) { 1427 int modPow(int e, int m) {
1396 if (e is! int) { 1428 if (e is! int) {
1397 throw new ArgumentError.value(e, "exponent", "not an integer"); 1429 throw new ArgumentError.value(e, "exponent", "not an integer");
1398 } 1430 }
1399 if (m is! int) { 1431 if (m is! int) {
1400 throw new ArgumentError.value(m, "modulus", "not an integer"); 1432 throw new ArgumentError.value(m, "modulus", "not an integer");
1401 } 1433 }
1402 if (e < 0) throw new RangeError.range(e, 0, null, "exponent"); 1434 if (e < 0) throw new RangeError.range(e, 0, null, "exponent");
1403 if (m <= 0) throw new RangeError.range(m, 1, null, "modulus"); 1435 if (m <= 0) throw new RangeError.range(m, 1, null, "modulus");
1404 if (e == 0) return 1; 1436 if (e == 0) return 1;
1405 m = m._toBigint(); 1437 m = m._toBigint();
1406 final m_used = m._used; 1438 final m_used = m._used;
1407 final m_used2p4 = 2 * m_used + 4; 1439 final m_used2p4 = 2 * m_used + 4;
1408 final e_bitlen = e.bitLength; 1440 final e_bitlen = e.bitLength;
1409 if (e_bitlen <= 0) return 1; 1441 if (e_bitlen <= 0) return 1;
1410 final bool cannotUseMontgomery = m.isEven || _abs() >= m; 1442 final bool cannotUseMontgomery = m.isEven || _abs() >= m;
1411 if (cannotUseMontgomery || e_bitlen < 64) { 1443 if (cannotUseMontgomery || e_bitlen < 64) {
1412 _Reduction z = (cannotUseMontgomery || e_bitlen < 8) ? 1444 _Reduction z = (cannotUseMontgomery || e_bitlen < 8)
1413 new _Classic(m) : new _Montgomery(m); 1445 ? new _Classic(m)
1446 : new _Montgomery(m);
1414 // TODO(regis): Should we use Barrett reduction for an even modulus and a 1447 // TODO(regis): Should we use Barrett reduction for an even modulus and a
1415 // large exponent? 1448 // large exponent?
1416 var r_digits = new Uint32List(m_used2p4); 1449 var r_digits = new Uint32List(m_used2p4);
1417 var r2_digits = new Uint32List(m_used2p4); 1450 var r2_digits = new Uint32List(m_used2p4);
1418 var g_digits = new Uint32List(m_used + (m_used & 1)); 1451 var g_digits = new Uint32List(m_used + (m_used & 1));
1419 var g_used = z._convert(this, g_digits); 1452 var g_used = z._convert(this, g_digits);
1420 // Initialize r with g. 1453 // Initialize r with g.
1421 var j = g_used + (g_used & 1); // Copy leading zero if any. 1454 var j = g_used + (g_used & 1); // Copy leading zero if any.
1422 while (--j >= 0) { 1455 while (--j >= 0) {
1423 r_digits[j] = g_digits[j]; 1456 r_digits[j] = g_digits[j];
1424 } 1457 }
1425 var r_used = g_used; 1458 var r_used = g_used;
1426 var r2_used; 1459 var r2_used;
1427 var i = e_bitlen - 1; 1460 var i = e_bitlen - 1;
1428 while (--i >= 0) { 1461 while (--i >= 0) {
1429 r2_used = z._sqr(r_digits, r_used, r2_digits); 1462 r2_used = z._sqr(r_digits, r_used, r2_digits);
1430 if ((e & (1 << i)) != 0) { 1463 if ((e & (1 << i)) != 0) {
1431 r_used = z._mul(r2_digits, r2_used, g_digits, g_used, r_digits); 1464 r_used = z._mul(r2_digits, r2_used, g_digits, g_used, r_digits);
1432 } else { 1465 } else {
1433 var t_digits = r_digits; 1466 var t_digits = r_digits;
1434 var t_used = r_used; 1467 var t_used = r_used;
1435 r_digits = r2_digits; 1468 r_digits = r2_digits;
1436 r_used = r2_used; 1469 r_used = r2_used;
1437 r2_digits = t_digits; 1470 r2_digits = t_digits;
1438 r2_used = t_used; 1471 r2_used = t_used;
1439 } 1472 }
1440 } 1473 }
1441 return z._revert(r_digits, r_used)._toValidInt(); 1474 return z._revert(r_digits, r_used)._toValidInt();
1442 } 1475 }
1443 e = e._toBigint(); 1476 e = e._toBigint();
1444 var k; 1477 var k;
1445 if (e_bitlen < 18) k = 1; 1478 if (e_bitlen < 18)
1446 else if (e_bitlen < 48) k = 3; 1479 k = 1;
1447 else if (e_bitlen < 144) k = 4; 1480 else if (e_bitlen < 48)
1448 else if (e_bitlen < 768) k = 5; 1481 k = 3;
1449 else k = 6; 1482 else if (e_bitlen < 144)
1483 k = 4;
1484 else if (e_bitlen < 768)
1485 k = 5;
1486 else
1487 k = 6;
1450 _Reduction z = new _Montgomery(m); 1488 _Reduction z = new _Montgomery(m);
1451 var n = 3; 1489 var n = 3;
1452 final k1 = k - 1; 1490 final k1 = k - 1;
1453 final km = (1 << k) - 1; 1491 final km = (1 << k) - 1;
1454 List g_digits = new List(km + 1); 1492 List g_digits = new List(km + 1);
1455 List g_used = new List(km + 1); 1493 List g_used = new List(km + 1);
1456 g_digits[1] = new Uint32List(m_used + (m_used & 1)); 1494 g_digits[1] = new Uint32List(m_used + (m_used & 1));
1457 g_used[1] = z._convert(this, g_digits[1]); 1495 g_used[1] = z._convert(this, g_digits[1]);
1458 if (k > 1) { 1496 if (k > 1) {
1459 var g2_digits = new Uint32List(m_used2p4); 1497 var g2_digits = new Uint32List(m_used2p4);
1460 var g2_used = z._sqr(g_digits[1], g_used[1], g2_digits); 1498 var g2_used = z._sqr(g_digits[1], g_used[1], g2_digits);
1461 while (n <= km) { 1499 while (n <= km) {
1462 g_digits[n] = new Uint32List(m_used2p4); 1500 g_digits[n] = new Uint32List(m_used2p4);
1463 g_used[n] = z._mul(g2_digits, g2_used, 1501 g_used[n] = z._mul(
1464 g_digits[n - 2], g_used[n - 2], 1502 g2_digits, g2_used, g_digits[n - 2], g_used[n - 2], g_digits[n]);
1465 g_digits[n]);
1466 n += 2; 1503 n += 2;
1467 } 1504 }
1468 } 1505 }
1469 var w; 1506 var w;
1470 var is1 = true; 1507 var is1 = true;
1471 var r_digits = _ONE._digits; 1508 var r_digits = _ONE._digits;
1472 var r_used = _ONE._used; 1509 var r_used = _ONE._used;
1473 var r2_digits = new Uint32List(m_used2p4); 1510 var r2_digits = new Uint32List(m_used2p4);
1474 var r2_used; 1511 var r2_used;
1475 var e_digits = e._digits; 1512 var e_digits = e._digits;
(...skipping 10 matching lines...) Expand all
1486 } 1523 }
1487 n = k; 1524 n = k;
1488 while ((w & 1) == 0) { 1525 while ((w & 1) == 0) {
1489 w >>= 1; 1526 w >>= 1;
1490 --n; 1527 --n;
1491 } 1528 }
1492 if ((i -= n) < 0) { 1529 if ((i -= n) < 0) {
1493 i += _DIGIT_BITS; 1530 i += _DIGIT_BITS;
1494 --j; 1531 --j;
1495 } 1532 }
1496 if (is1) { // r == 1, don't bother squaring or multiplying it. 1533 if (is1) {
1534 // r == 1, don't bother squaring or multiplying it.
1497 r_digits = new Uint32List(m_used2p4); 1535 r_digits = new Uint32List(m_used2p4);
1498 r_used = g_used[w]; 1536 r_used = g_used[w];
1499 var gw_digits = g_digits[w]; 1537 var gw_digits = g_digits[w];
1500 var ri = r_used + (r_used & 1); // Copy leading zero if any. 1538 var ri = r_used + (r_used & 1); // Copy leading zero if any.
1501 while (--ri >= 0) { 1539 while (--ri >= 0) {
1502 r_digits[ri] = gw_digits[ri]; 1540 r_digits[ri] = gw_digits[ri];
1503 } 1541 }
1504 is1 = false; 1542 is1 = false;
1505 } 1543 } else {
1506 else {
1507 while (n > 1) { 1544 while (n > 1) {
1508 r2_used = z._sqr(r_digits, r_used, r2_digits); 1545 r2_used = z._sqr(r_digits, r_used, r2_digits);
1509 r_used = z._sqr(r2_digits, r2_used, r_digits); 1546 r_used = z._sqr(r2_digits, r2_used, r_digits);
1510 n -= 2; 1547 n -= 2;
1511 } 1548 }
1512 if (n > 0) { 1549 if (n > 0) {
1513 r2_used = z._sqr(r_digits, r_used, r2_digits); 1550 r2_used = z._sqr(r_digits, r_used, r2_digits);
1514 } else { 1551 } else {
1515 var t_digits = r_digits; 1552 var t_digits = r_digits;
1516 var t_used = r_used; 1553 var t_used = r_used;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1581 if ((y_digits[0] & 1) == 1) { 1618 if ((y_digits[0] & 1) == 1) {
1582 var t_digits = x_digits; 1619 var t_digits = x_digits;
1583 var t_used = x_used; 1620 var t_used = x_used;
1584 x_digits = y_digits; 1621 x_digits = y_digits;
1585 x_used = y_used; 1622 x_used = y_used;
1586 y_digits = t_digits; 1623 y_digits = t_digits;
1587 y_used = t_used; 1624 y_used = t_used;
1588 } 1625 }
1589 } 1626 }
1590 var u_digits = _cloneDigits(x_digits, 0, x_used, m_len); 1627 var u_digits = _cloneDigits(x_digits, 0, x_used, m_len);
1591 var v_digits = _cloneDigits(y_digits, 0, y_used, m_len + 2); // +2 for lsh. 1628 var v_digits = _cloneDigits(y_digits, 0, y_used, m_len + 2); // +2 for lsh.
1592 final bool ac = (x_digits[0] & 1) == 0; 1629 final bool ac = (x_digits[0] & 1) == 0;
1593 1630
1594 // Variables a, b, c, and d require one more digit. 1631 // Variables a, b, c, and d require one more digit.
1595 final abcd_used = m_used + 1; 1632 final abcd_used = m_used + 1;
1596 final abcd_len = abcd_used + (abcd_used & 1) + 2; // +2 to satisfy _absAdd. 1633 final abcd_len = abcd_used + (abcd_used & 1) + 2; // +2 to satisfy _absAdd.
1597 var a_digits, b_digits, c_digits, d_digits; 1634 var a_digits, b_digits, c_digits, d_digits;
1598 bool a_neg, b_neg, c_neg, d_neg; 1635 bool a_neg, b_neg, c_neg, d_neg;
1599 if (ac) { 1636 if (ac) {
1600 a_digits = new Uint32List(abcd_len); 1637 a_digits = new Uint32List(abcd_len);
1601 a_neg = false; 1638 a_neg = false;
1602 a_digits[0] = 1; 1639 a_digits[0] = 1;
1603 c_digits = new Uint32List(abcd_len); 1640 c_digits = new Uint32List(abcd_len);
1604 c_neg = false; 1641 c_neg = false;
1605 } 1642 }
1606 b_digits = new Uint32List(abcd_len); 1643 b_digits = new Uint32List(abcd_len);
(...skipping 26 matching lines...) Expand all
1633 } else { 1670 } else {
1634 _absSub(x_digits, m_used, b_digits, m_used, b_digits); 1671 _absSub(x_digits, m_used, b_digits, m_used, b_digits);
1635 b_neg = true; 1672 b_neg = true;
1636 } 1673 }
1637 } 1674 }
1638 _rsh(a_digits, abcd_used, 1, a_digits); 1675 _rsh(a_digits, abcd_used, 1, a_digits);
1639 } else if ((b_digits[0] & 1) == 1) { 1676 } else if ((b_digits[0] & 1) == 1) {
1640 if (b_neg) { 1677 if (b_neg) {
1641 _absAdd(b_digits, abcd_used, x_digits, m_used, b_digits); 1678 _absAdd(b_digits, abcd_used, x_digits, m_used, b_digits);
1642 } else if ((b_digits[m_used] != 0) || 1679 } else if ((b_digits[m_used] != 0) ||
1643 (_compareDigits(b_digits, m_used, x_digits, m_used) > 0)) { 1680 (_compareDigits(b_digits, m_used, x_digits, m_used) > 0)) {
1644 _absSub(b_digits, abcd_used, x_digits, m_used, b_digits); 1681 _absSub(b_digits, abcd_used, x_digits, m_used, b_digits);
1645 } else { 1682 } else {
1646 _absSub(x_digits, m_used, b_digits, m_used, b_digits); 1683 _absSub(x_digits, m_used, b_digits, m_used, b_digits);
1647 b_neg = true; 1684 b_neg = true;
1648 } 1685 }
1649 } 1686 }
1650 _rsh(b_digits, abcd_used, 1, b_digits); 1687 _rsh(b_digits, abcd_used, 1, b_digits);
1651 } 1688 }
1652 while ((v_digits[0] & 1) == 0) { 1689 while ((v_digits[0] & 1) == 0) {
1653 _rsh(v_digits, m_used, 1, v_digits); 1690 _rsh(v_digits, m_used, 1, v_digits);
(...skipping 18 matching lines...) Expand all
1672 } else { 1709 } else {
1673 _absSub(x_digits, m_used, d_digits, m_used, d_digits); 1710 _absSub(x_digits, m_used, d_digits, m_used, d_digits);
1674 d_neg = true; 1711 d_neg = true;
1675 } 1712 }
1676 } 1713 }
1677 _rsh(c_digits, abcd_used, 1, c_digits); 1714 _rsh(c_digits, abcd_used, 1, c_digits);
1678 } else if ((d_digits[0] & 1) == 1) { 1715 } else if ((d_digits[0] & 1) == 1) {
1679 if (d_neg) { 1716 if (d_neg) {
1680 _absAdd(d_digits, abcd_used, x_digits, m_used, d_digits); 1717 _absAdd(d_digits, abcd_used, x_digits, m_used, d_digits);
1681 } else if ((d_digits[m_used] != 0) || 1718 } else if ((d_digits[m_used] != 0) ||
1682 (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) { 1719 (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
1683 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits); 1720 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
1684 } else { 1721 } else {
1685 _absSub(x_digits, m_used, d_digits, m_used, d_digits); 1722 _absSub(x_digits, m_used, d_digits, m_used, d_digits);
1686 d_neg = true; 1723 d_neg = true;
1687 } 1724 }
1688 } 1725 }
1689 _rsh(d_digits, abcd_used, 1, d_digits); 1726 _rsh(d_digits, abcd_used, 1, d_digits);
1690 } 1727 }
1691 if (_compareDigits(u_digits, m_used, v_digits, m_used) >= 0) { 1728 if (_compareDigits(u_digits, m_used, v_digits, m_used) >= 0) {
1692 _absSub(u_digits, m_used, v_digits, m_used, u_digits); 1729 _absSub(u_digits, m_used, v_digits, m_used, u_digits);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits); 1809 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
1773 } else { 1810 } else {
1774 _absSub(x_digits, m_used, d_digits, m_used, d_digits); 1811 _absSub(x_digits, m_used, d_digits, m_used, d_digits);
1775 d_neg = false; 1812 d_neg = false;
1776 } 1813 }
1777 } else { 1814 } else {
1778 _absSub(x_digits, m_used, d_digits, m_used, d_digits); 1815 _absSub(x_digits, m_used, d_digits, m_used, d_digits);
1779 d_neg = false; 1816 d_neg = false;
1780 } 1817 }
1781 } else if ((d_digits[m_used] != 0) || 1818 } else if ((d_digits[m_used] != 0) ||
1782 (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) { 1819 (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
1783 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits); 1820 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
1784 if ((d_digits[m_used] != 0) || 1821 if ((d_digits[m_used] != 0) ||
1785 (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) { 1822 (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
1786 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits); 1823 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
1787 } 1824 }
1788 } 1825 }
1789 return new _Bigint(false, m_used, d_digits)._toValidInt(); 1826 return new _Bigint(false, m_used, d_digits)._toValidInt();
1790 } 1827 }
1791 1828
1792 // Returns 1/this % m, with m > 0. 1829 // Returns 1/this % m, with m > 0.
(...skipping 21 matching lines...) Expand all
1814 return this.abs(); 1851 return this.abs();
1815 } 1852 }
1816 return _binaryGcd(this, other._toBigint(), false); 1853 return _binaryGcd(this, other._toBigint(), false);
1817 } 1854 }
1818 } 1855 }
1819 1856
1820 // Interface for modular reduction. 1857 // Interface for modular reduction.
1821 class _Reduction { 1858 class _Reduction {
1822 // Return the number of digits used by r_digits. 1859 // Return the number of digits used by r_digits.
1823 int _convert(_Bigint x, Uint32List r_digits); 1860 int _convert(_Bigint x, Uint32List r_digits);
1824 int _mul(Uint32List x_digits, int x_used, 1861 int _mul(Uint32List x_digits, int x_used, Uint32List y_digits, int y_used,
1825 Uint32List y_digits, int y_used, Uint32List r_digits); 1862 Uint32List r_digits);
1826 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits); 1863 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits);
1827 1864
1828 // Return x reverted to _Bigint. 1865 // Return x reverted to _Bigint.
1829 _Bigint _revert(Uint32List x_digits, int x_used); 1866 _Bigint _revert(Uint32List x_digits, int x_used);
1830 } 1867 }
1831 1868
1832 // Montgomery reduction on _Bigint. 1869 // Montgomery reduction on _Bigint.
1833 class _Montgomery implements _Reduction { 1870 class _Montgomery implements _Reduction {
1834 _Bigint _m; // Modulus. 1871 _Bigint _m; // Modulus.
1835 int _mused2p2; 1872 int _mused2p2;
1836 Uint32List _args; 1873 Uint32List _args;
1837 int _digits_per_step; // Number of digits processed in one step. 1 or 2. 1874 int _digits_per_step; // Number of digits processed in one step. 1 or 2.
1838 static const int _X = 0; // Index of x. 1875 static const int _X = 0; // Index of x.
1839 static const int _X_HI = 1; // Index of high 32-bits of x (64-bit only). 1876 static const int _X_HI = 1; // Index of high 32-bits of x (64-bit only).
1840 static const int _RHO = 2; // Index of rho. 1877 static const int _RHO = 2; // Index of rho.
1841 static const int _RHO_HI = 3; // Index of high 32-bits of rho (64-bit only). 1878 static const int _RHO_HI = 3; // Index of high 32-bits of rho (64-bit only).
1842 static const int _MU = 4; // Index of mu. 1879 static const int _MU = 4; // Index of mu.
1843 static const int _MU_HI = 5; // Index of high 32-bits of mu (64-bit only). 1880 static const int _MU_HI = 5; // Index of high 32-bits of mu (64-bit only).
1844 1881
1845 _Montgomery(m) { 1882 _Montgomery(m) {
1846 _m = m._toBigint(); 1883 _m = m._toBigint();
1847 _mused2p2 = 2*_m._used + 2; 1884 _mused2p2 = 2 * _m._used + 2;
1848 _args = new Uint32List(6); 1885 _args = new Uint32List(6);
1849 // Determine if we can process digit pairs by calling an intrinsic. 1886 // Determine if we can process digit pairs by calling an intrinsic.
1850 _digits_per_step = _mulMod(_args, _args, 0); 1887 _digits_per_step = _mulMod(_args, _args, 0);
1851 _args[_X] = _m._digits[0]; 1888 _args[_X] = _m._digits[0];
1852 if (_digits_per_step == 1) { 1889 if (_digits_per_step == 1) {
1853 _invDigit(_args); 1890 _invDigit(_args);
1854 } else { 1891 } else {
1855 assert(_digits_per_step == 2); 1892 assert(_digits_per_step == 2);
1856 _args[_X_HI] = _m._digits[1]; 1893 _args[_X_HI] = _m._digits[1];
1857 _invDigitPair(_args); 1894 _invDigitPair(_args);
1858 } 1895 }
1859 } 1896 }
1860 1897
1861 // Calculates -1/x % _DIGIT_BASE, x is 32-bit digit. 1898 // Calculates -1/x % _DIGIT_BASE, x is 32-bit digit.
1862 // xy == 1 (mod m) 1899 // xy == 1 (mod m)
1863 // xy = 1+km 1900 // xy = 1+km
1864 // xy(2-xy) = (1+km)(1-km) 1901 // xy(2-xy) = (1+km)(1-km)
1865 // x(y(2-xy)) = 1-k^2 m^2 1902 // x(y(2-xy)) = 1-k^2 m^2
1866 // x(y(2-xy)) == 1 (mod m^2) 1903 // x(y(2-xy)) == 1 (mod m^2)
1867 // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 1904 // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
1868 // Should reduce x and y(2-xy) by m^2 at each step to keep size bounded. 1905 // Should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
1869 // 1906 //
1870 // Operation: 1907 // Operation:
1871 // args[_RHO] = 1/args[_X] mod _DIGIT_BASE. 1908 // args[_RHO] = 1/args[_X] mod _DIGIT_BASE.
1872 static void _invDigit(Uint32List args) { 1909 static void _invDigit(Uint32List args) {
1873 var x = args[_X]; 1910 var x = args[_X];
1874 var y = x & 3; // y == 1/x mod 2^2 1911 var y = x & 3; // y == 1/x mod 2^2
1875 y = (y*(2 - (x & 0xf)*y)) & 0xf; // y == 1/x mod 2^4 1912 y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
1876 y = (y*(2 - (x & 0xff)*y)) & 0xff; // y == 1/x mod 2^8 1913 y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
1877 y = (y*(2 - (((x & 0xffff)*y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 1914 y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
1878 // Last step - calculate inverse mod _DIGIT_BASE directly; 1915 // Last step - calculate inverse mod _DIGIT_BASE directly;
1879 // Assumes 16 < _DIGIT_BITS <= 32 and assumes ability to handle 48-bit ints. 1916 // Assumes 16 < _DIGIT_BITS <= 32 and assumes ability to handle 48-bit ints.
1880 y = (y*(2 - x*y % _Bigint._DIGIT_BASE)) % _Bigint._DIGIT_BASE; 1917 y = (y * (2 - x * y % _Bigint._DIGIT_BASE)) % _Bigint._DIGIT_BASE;
1881 // y == 1/x mod _DIGIT_BASE 1918 // y == 1/x mod _DIGIT_BASE
1882 y = -y; // We really want the negative inverse. 1919 y = -y; // We really want the negative inverse.
1883 args[_RHO] = y & _Bigint._DIGIT_MASK; 1920 args[_RHO] = y & _Bigint._DIGIT_MASK;
1884 } 1921 }
1885 1922
1886 // Calculates -1/x % _DIGIT_BASE^2, x is a pair of 32-bit digits. 1923 // Calculates -1/x % _DIGIT_BASE^2, x is a pair of 32-bit digits.
1887 // Operation: 1924 // Operation:
1888 // args[_RHO.._RHO_HI] = 1/args[_X.._X_HI] mod _DIGIT_BASE^2. 1925 // args[_RHO.._RHO_HI] = 1/args[_X.._X_HI] mod _DIGIT_BASE^2.
1889 static void _invDigitPair(Uint32List args) { 1926 static void _invDigitPair(Uint32List args) {
1890 var xl = args[_X]; // Lower 32-bit digit of x. 1927 var xl = args[_X]; // Lower 32-bit digit of x.
1891 var y = xl & 3; // y == 1/x mod 2^2 1928 var y = xl & 3; // y == 1/x mod 2^2
1892 y = (y*(2 - (xl & 0xf)*y)) & 0xf; // y == 1/x mod 2^4 1929 y = (y * (2 - (xl & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
1893 y = (y*(2 - (xl & 0xff)*y)) & 0xff; // y == 1/x mod 2^8 1930 y = (y * (2 - (xl & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
1894 y = (y*(2 - (((xl & 0xffff)*y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 1931 y = (y * (2 - (((xl & 0xffff) * y) & 0xffff))) &
1895 y = (y*(2 - ((xl*y) & 0xffffffff))) & 0xffffffff; // y == 1/x mod 2^32 1932 0xffff; // y == 1/x mod 2^16
1933 y = (y * (2 - ((xl * y) & 0xffffffff))) & 0xffffffff; // y == 1/x mod 2^32
1896 var x = (args[_X_HI] << _Bigint._DIGIT_BITS) | xl; 1934 var x = (args[_X_HI] << _Bigint._DIGIT_BITS) | xl;
1897 y = (y*(2 - ((x*y) & 0xffffffffffffffff))) & 0xffffffffffffffff; 1935 y = (y * (2 - ((x * y) & 0xffffffffffffffff))) & 0xffffffffffffffff;
1898 // y == 1/x mod _DIGIT_BASE^2 1936 // y == 1/x mod _DIGIT_BASE^2
1899 y = -y; // We really want the negative inverse. 1937 y = -y; // We really want the negative inverse.
1900 args[_RHO] = y & _Bigint._DIGIT_MASK; 1938 args[_RHO] = y & _Bigint._DIGIT_MASK;
1901 args[_RHO_HI] = (y >> _Bigint._DIGIT_BITS) & _Bigint._DIGIT_MASK; 1939 args[_RHO_HI] = (y >> _Bigint._DIGIT_BITS) & _Bigint._DIGIT_MASK;
1902 } 1940 }
1903 1941
1904 // Operation: 1942 // Operation:
1905 // args[_MU] = args[_RHO]*digits[i] mod _DIGIT_BASE. 1943 // args[_MU] = args[_RHO]*digits[i] mod _DIGIT_BASE.
1906 // return 1. 1944 // return 1.
1907 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices: 1945 // Note: Intrinsics on 64-bit platforms process digit pairs at even indices:
1908 // args[_MU.._MU_HI] = args[_RHO.._RHO_HI]*digits[i..i+1] mod _DIGIT_BASE^2. 1946 // args[_MU.._MU_HI] = args[_RHO.._RHO_HI]*digits[i..i+1] mod _DIGIT_BASE^2.
1909 // return 2. 1947 // return 2.
1910 static int _mulMod(Uint32List args, Uint32List digits, int i) { 1948 static int _mulMod(Uint32List args, Uint32List digits, int i) {
1911 // Verify that digit pairs are accessible for 64-bit processing. 1949 // Verify that digit pairs are accessible for 64-bit processing.
1912 assert(digits.length > (i | 1)); 1950 assert(digits.length > (i | 1));
1913 const int MU_MASK = (1 << (_Bigint._DIGIT_BITS - _Bigint._DIGIT2_BITS)) - 1; 1951 const int MU_MASK = (1 << (_Bigint._DIGIT_BITS - _Bigint._DIGIT2_BITS)) - 1;
1914 var rhol = args[_RHO] & _Bigint._DIGIT2_MASK; 1952 var rhol = args[_RHO] & _Bigint._DIGIT2_MASK;
1915 var rhoh = args[_RHO] >> _Bigint._DIGIT2_BITS; 1953 var rhoh = args[_RHO] >> _Bigint._DIGIT2_BITS;
1916 var dh = digits[i] >> _Bigint._DIGIT2_BITS; 1954 var dh = digits[i] >> _Bigint._DIGIT2_BITS;
1917 var dl = digits[i] & _Bigint._DIGIT2_MASK; 1955 var dl = digits[i] & _Bigint._DIGIT2_MASK;
1918 args[_MU] = 1956 args[_MU] = (dl * rhol +
1919 (dl*rhol + (((dl*rhoh + dh*rhol) & MU_MASK) << _Bigint._DIGIT2_BITS)) 1957 (((dl * rhoh + dh * rhol) & MU_MASK) << _Bigint._DIGIT2_BITS)) &
1920 & _Bigint._DIGIT_MASK; 1958 _Bigint._DIGIT_MASK;
1921 return 1; 1959 return 1;
1922 } 1960 }
1923 1961
1924 // r = x*R mod _m. 1962 // r = x*R mod _m.
1925 // Return r_used. 1963 // Return r_used.
1926 int _convert(_Bigint x, Uint32List r_digits) { 1964 int _convert(_Bigint x, Uint32List r_digits) {
1927 // Montgomery reduction only works if abs(x) < _m. 1965 // Montgomery reduction only works if abs(x) < _m.
1928 assert(x._abs() < _m); 1966 assert(x._abs() < _m);
1929 var r = x._abs()._dlShift(_m._used)._rem(_m); 1967 var r = x._abs()._dlShift(_m._used)._rem(_m);
1930 if (x._neg && !r._neg && r._used > 0) { 1968 if (x._neg && !r._neg && r._used > 0) {
(...skipping 14 matching lines...) Expand all
1945 while (--i >= 0) { 1983 while (--i >= 0) {
1946 r_digits[i] = x_digits[i]; 1984 r_digits[i] = x_digits[i];
1947 } 1985 }
1948 var r_used = _reduce(r_digits, x_used); 1986 var r_used = _reduce(r_digits, x_used);
1949 return new _Bigint(false, r_used, r_digits); 1987 return new _Bigint(false, r_used, r_digits);
1950 } 1988 }
1951 1989
1952 // x = x/R mod _m. 1990 // x = x/R mod _m.
1953 // Return x_used. 1991 // Return x_used.
1954 int _reduce(Uint32List x_digits, int x_used) { 1992 int _reduce(Uint32List x_digits, int x_used) {
1955 while (x_used < _mused2p2) { // Pad x so _mulAdd has enough room later. 1993 while (x_used < _mused2p2) {
1994 // Pad x so _mulAdd has enough room later.
1956 x_digits[x_used++] = 0; 1995 x_digits[x_used++] = 0;
1957 } 1996 }
1958 var m_used = _m._used; 1997 var m_used = _m._used;
1959 var m_digits = _m._digits; 1998 var m_digits = _m._digits;
1960 var i = 0; 1999 var i = 0;
1961 while (i < m_used) { 2000 while (i < m_used) {
1962 var d = _mulMod(_args, x_digits, i); 2001 var d = _mulMod(_args, x_digits, i);
1963 assert(d == _digits_per_step); 2002 assert(d == _digits_per_step);
1964 d = _Bigint._mulAdd(_args, _MU, m_digits, 0, x_digits, i, m_used); 2003 d = _Bigint._mulAdd(_args, _MU, m_digits, 0, x_digits, i, m_used);
1965 assert(d == _digits_per_step); 2004 assert(d == _digits_per_step);
(...skipping 13 matching lines...) Expand all
1979 --x_used; 2018 --x_used;
1980 } 2019 }
1981 return x_used; 2020 return x_used;
1982 } 2021 }
1983 2022
1984 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits) { 2023 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits) {
1985 var r_used = _Bigint._sqrDigits(x_digits, x_used, r_digits); 2024 var r_used = _Bigint._sqrDigits(x_digits, x_used, r_digits);
1986 return _reduce(r_digits, r_used); 2025 return _reduce(r_digits, r_used);
1987 } 2026 }
1988 2027
1989 int _mul(Uint32List x_digits, int x_used, 2028 int _mul(Uint32List x_digits, int x_used, Uint32List y_digits, int y_used,
1990 Uint32List y_digits, int y_used, 2029 Uint32List r_digits) {
1991 Uint32List r_digits) { 2030 var r_used =
1992 var r_used = _Bigint._mulDigits(x_digits, x_used, 2031 _Bigint._mulDigits(x_digits, x_used, y_digits, y_used, r_digits);
1993 y_digits, y_used,
1994 r_digits);
1995 return _reduce(r_digits, r_used); 2032 return _reduce(r_digits, r_used);
1996 } 2033 }
1997 } 2034 }
1998 2035
1999 // Modular reduction using "classic" algorithm. 2036 // Modular reduction using "classic" algorithm.
2000 class _Classic implements _Reduction { 2037 class _Classic implements _Reduction {
2001 _Bigint _m; // Modulus. 2038 _Bigint _m; // Modulus.
2002 _Bigint _norm_m; // Normalized _m. 2039 _Bigint _norm_m; // Normalized _m.
2003 Uint32List _neg_norm_m_digits; // Negated _norm_m digits. 2040 Uint32List _neg_norm_m_digits; // Negated _norm_m digits.
2004 int _m_nsh; // Normalization shift amount. 2041 int _m_nsh; // Normalization shift amount.
2005 Uint32List _mt_qd; // Top _norm_m digit(s) and place holder for 2042 Uint32List _mt_qd; // Top _norm_m digit(s) and place holder for
2006 // estimated quotient digit(s). 2043 // estimated quotient digit(s).
2007 Uint32List _t_digits; // Temporary digits used during reduction. 2044 Uint32List _t_digits; // Temporary digits used during reduction.
2008 2045
2009 _Classic(int m) { 2046 _Classic(int m) {
2010 _m = m._toBigint(); 2047 _m = m._toBigint();
2011 // Preprocess arguments to _remDigits. 2048 // Preprocess arguments to _remDigits.
2012 var nsh = _Bigint._DIGIT_BITS - _Bigint._nbits(_m._digits[_m._used - 1]); 2049 var nsh = _Bigint._DIGIT_BITS - _Bigint._nbits(_m._digits[_m._used - 1]);
2013 // For 64-bit processing, make sure _norm_m_digits has an even number of 2050 // For 64-bit processing, make sure _norm_m_digits has an even number of
2014 // digits. 2051 // digits.
2015 if (_m._used.isOdd) { 2052 if (_m._used.isOdd) {
2016 nsh += _Bigint._DIGIT_BITS; 2053 nsh += _Bigint._DIGIT_BITS;
2017 } 2054 }
2018 _m_nsh = nsh; 2055 _m_nsh = nsh;
2019 _norm_m = _m._lShift(nsh); 2056 _norm_m = _m._lShift(nsh);
2020 var nm_used = _norm_m._used; 2057 var nm_used = _norm_m._used;
2021 assert(nm_used.isEven); 2058 assert(nm_used.isEven);
2022 _mt_qd = new Uint32List(4); 2059 _mt_qd = new Uint32List(4);
2023 _mt_qd[_Bigint._YT_LO] = _norm_m._digits[nm_used - 2]; 2060 _mt_qd[_Bigint._YT_LO] = _norm_m._digits[nm_used - 2];
2024 _mt_qd[_Bigint._YT] = _norm_m._digits[nm_used - 1]; 2061 _mt_qd[_Bigint._YT] = _norm_m._digits[nm_used - 1];
2025 // Negate _norm_m so we can use _mulAdd instead of unimplemented _mulSub. 2062 // Negate _norm_m so we can use _mulAdd instead of unimplemented _mulSub.
2026 var neg_norm_m = _Bigint._ONE._dlShift(nm_used)._sub(_norm_m); 2063 var neg_norm_m = _Bigint._ONE._dlShift(nm_used)._sub(_norm_m);
2027 if (neg_norm_m._used < nm_used) { 2064 if (neg_norm_m._used < nm_used) {
2028 _neg_norm_m_digits = 2065 _neg_norm_m_digits =
2029 _Bigint._cloneDigits(neg_norm_m._digits, 0, nm_used, nm_used); 2066 _Bigint._cloneDigits(neg_norm_m._digits, 0, nm_used, nm_used);
2030 } else { 2067 } else {
2031 _neg_norm_m_digits = neg_norm_m._digits; 2068 _neg_norm_m_digits = neg_norm_m._digits;
2032 } 2069 }
2033 // _neg_norm_m_digits is read-only and has nm_used digits (possibly 2070 // _neg_norm_m_digits is read-only and has nm_used digits (possibly
2034 // including several leading zeros) plus a leading zero for 64-bit 2071 // including several leading zeros) plus a leading zero for 64-bit
2035 // processing. 2072 // processing.
2036 _t_digits = new Uint32List(2*nm_used); 2073 _t_digits = new Uint32List(2 * nm_used);
2037 } 2074 }
2038 2075
2039 int _convert(_Bigint x, Uint32List r_digits) { 2076 int _convert(_Bigint x, Uint32List r_digits) {
2040 var digits; 2077 var digits;
2041 var used; 2078 var used;
2042 if (x._neg || x._compare(_m) >= 0) { 2079 if (x._neg || x._compare(_m) >= 0) {
2043 var r = x._rem(_m); 2080 var r = x._rem(_m);
2044 if (x._neg && !r._neg && r._used > 0) { 2081 if (x._neg && !r._neg && r._used > 0) {
2045 r = _m._sub(r); 2082 r = _m._sub(r);
2046 } 2083 }
2047 assert(!r._neg); 2084 assert(!r._neg);
2048 used = r._used; 2085 used = r._used;
2049 digits = r._digits; 2086 digits = r._digits;
2050 } else { 2087 } else {
2051 used = x._used; 2088 used = x._used;
2052 digits = x._digits; 2089 digits = x._digits;
2053 } 2090 }
2054 var i = used + (used & 1); // Copy leading zero if any. 2091 var i = used + (used & 1); // Copy leading zero if any.
2055 while (--i >= 0) { 2092 while (--i >= 0) {
2056 r_digits[i] = digits[i]; 2093 r_digits[i] = digits[i];
2057 } 2094 }
2058 return used; 2095 return used;
2059 } 2096 }
2060 2097
2061 _Bigint _revert(Uint32List x_digits, int x_used) { 2098 _Bigint _revert(Uint32List x_digits, int x_used) {
2062 return new _Bigint(false, x_used, x_digits); 2099 return new _Bigint(false, x_used, x_digits);
2063 } 2100 }
2064 2101
2065 int _reduce(Uint32List x_digits, int x_used) { 2102 int _reduce(Uint32List x_digits, int x_used) {
2066 if (x_used < _m._used) { 2103 if (x_used < _m._used) {
2067 return x_used; 2104 return x_used;
2068 } 2105 }
2069 // The function _remDigits(...) is optimized for reduction and equivalent to 2106 // The function _remDigits(...) is optimized for reduction and equivalent to
2070 // calling _convert(_revert(x_digits, x_used)._rem(_m), x_digits); 2107 // calling _convert(_revert(x_digits, x_used)._rem(_m), x_digits);
2071 return _Bigint._remDigits(x_digits, x_used, 2108 return _Bigint._remDigits(x_digits, x_used, _norm_m._digits, _norm_m._used,
2072 _norm_m._digits, _norm_m._used, 2109 _neg_norm_m_digits, _m_nsh, _mt_qd, _t_digits, x_digits);
2073 _neg_norm_m_digits,
2074 _m_nsh,
2075 _mt_qd,
2076 _t_digits,
2077 x_digits);
2078 } 2110 }
2079 2111
2080 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits) { 2112 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits) {
2081 var r_used = _Bigint._sqrDigits(x_digits, x_used, r_digits); 2113 var r_used = _Bigint._sqrDigits(x_digits, x_used, r_digits);
2082 return _reduce(r_digits, r_used); 2114 return _reduce(r_digits, r_used);
2083 } 2115 }
2084 2116
2085 int _mul(Uint32List x_digits, int x_used, 2117 int _mul(Uint32List x_digits, int x_used, Uint32List y_digits, int y_used,
2086 Uint32List y_digits, int y_used, 2118 Uint32List r_digits) {
2087 Uint32List r_digits) { 2119 var r_used =
2088 var r_used = _Bigint._mulDigits(x_digits, x_used, 2120 _Bigint._mulDigits(x_digits, x_used, y_digits, y_used, r_digits);
2089 y_digits, y_used,
2090 r_digits);
2091 return _reduce(r_digits, r_used); 2121 return _reduce(r_digits, r_used);
2092 } 2122 }
2093 } 2123 }
OLDNEW
« no previous file with comments | « runtime/lib/async_patch.dart ('k') | runtime/lib/bool_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698