OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of _interceptors; | 5 part of _interceptors; |
6 | 6 |
7 /** | 7 /** |
8 * The super interceptor class for [JSInt] and [JSDouble]. The compiler | 8 * The super interceptor class for [JSInt] and [JSDouble]. The compiler |
9 * recognizes this class as an interceptor, and changes references to | 9 * recognizes this class as an interceptor, and changes references to |
10 * [:this:] to actually use the receiver of the method, which is | 10 * [:this:] to actually use the receiver of the method, which is |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 while (e > 0) { | 404 while (e > 0) { |
405 if (e.isOdd) { | 405 if (e.isOdd) { |
406 r = (r * b) % m; | 406 r = (r * b) % m; |
407 } | 407 } |
408 e ~/= 2; | 408 e ~/= 2; |
409 b = (b * b) % m; | 409 b = (b * b) % m; |
410 } | 410 } |
411 return r; | 411 return r; |
412 } | 412 } |
413 | 413 |
| 414 // Returns 1/this % m, with m > 0. |
| 415 int modInverse(int m) { |
| 416 if (m is! int) throw new ArgumentError(m); |
| 417 if (m <= 0) throw new RangeError(m); |
| 418 if (m is _Bigint) { |
| 419 return _toBigint().modInverse(m); |
| 420 } |
| 421 bool ac = m.isEven; |
| 422 int u = m; |
| 423 int v = this; |
| 424 int a = 1, |
| 425 b = 0, |
| 426 c = 0, |
| 427 d = 1; |
| 428 while (u != 0) { |
| 429 while (u.isEven) { |
| 430 u ~/= 2; |
| 431 if (ac) { |
| 432 if (!a.isEven || !b.isEven) { |
| 433 a += this; |
| 434 b -= m; |
| 435 } |
| 436 a ~/= 2; |
| 437 } else if (!b.isEven) { |
| 438 b -= m; |
| 439 } |
| 440 b ~/= 2; |
| 441 } |
| 442 while (v.isEven) { |
| 443 v ~/= 2; |
| 444 if (ac) { |
| 445 if (!c.isEven || !d.isEven) { |
| 446 c += this; |
| 447 d -= m; |
| 448 } |
| 449 c ~/= 2; |
| 450 } else if (!d.isEven) { |
| 451 d -= m; |
| 452 } |
| 453 d ~/= 2; |
| 454 } |
| 455 if (u >= v) { |
| 456 u -= v; |
| 457 if (ac) a -= c; |
| 458 b -= d; |
| 459 } else { |
| 460 v -= u; |
| 461 if (ac) c -= a; |
| 462 d -= b; |
| 463 } |
| 464 } |
| 465 if (v != 1) return 0; |
| 466 if (d > m) return d - m; |
| 467 if (d < 0) d += m; |
| 468 if (d < 0) d += m; |
| 469 return d; |
| 470 } |
| 471 |
414 // Assumes i is <= 32-bit and unsigned. | 472 // Assumes i is <= 32-bit and unsigned. |
415 static int _bitCount(int i) { | 473 static int _bitCount(int i) { |
416 // See "Hacker's Delight", section 5-1, "Counting 1-Bits". | 474 // See "Hacker's Delight", section 5-1, "Counting 1-Bits". |
417 | 475 |
418 // The basic strategy is to use "divide and conquer" to | 476 // The basic strategy is to use "divide and conquer" to |
419 // add pairs (then quads, etc.) of bits together to obtain | 477 // add pairs (then quads, etc.) of bits together to obtain |
420 // sub-counts. | 478 // sub-counts. |
421 // | 479 // |
422 // A straightforward approach would look like: | 480 // A straightforward approach would look like: |
423 // | 481 // |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 } | 516 } |
459 | 517 |
460 class JSDouble extends JSNumber implements double { | 518 class JSDouble extends JSNumber implements double { |
461 const JSDouble(); | 519 const JSDouble(); |
462 Type get runtimeType => double; | 520 Type get runtimeType => double; |
463 } | 521 } |
464 | 522 |
465 class JSPositiveInt extends JSInt {} | 523 class JSPositiveInt extends JSInt {} |
466 class JSUInt32 extends JSPositiveInt {} | 524 class JSUInt32 extends JSPositiveInt {} |
467 class JSUInt31 extends JSUInt32 {} | 525 class JSUInt31 extends JSUInt32 {} |
OLD | NEW |