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

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

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