| OLD | NEW |
| 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 // Copyright 2009 The Go Authors. All rights reserved. | 5 // Copyright 2009 The Go Authors. All rights reserved. |
| 6 // Use of this source code is governed by a BSD-style | 6 // Use of this source code is governed by a BSD-style |
| 7 // license that can be found in the LICENSE file. | 7 // license that can be found in the LICENSE file. |
| 8 | 8 |
| 9 /* | 9 /* |
| 10 * Copyright (c) 2003-2005 Tom Wu | 10 * Copyright (c) 2003-2005 Tom Wu |
| (...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 num operator +(num other) { | 1258 num operator +(num other) { |
| 1259 return other._toBigintOrDouble()._addFromInteger(this); | 1259 return other._toBigintOrDouble()._addFromInteger(this); |
| 1260 } | 1260 } |
| 1261 num operator -(num other) { | 1261 num operator -(num other) { |
| 1262 return other._toBigintOrDouble()._subFromInteger(this); | 1262 return other._toBigintOrDouble()._subFromInteger(this); |
| 1263 } | 1263 } |
| 1264 num operator *(num other) { | 1264 num operator *(num other) { |
| 1265 return other._toBigintOrDouble()._mulFromInteger(this); | 1265 return other._toBigintOrDouble()._mulFromInteger(this); |
| 1266 } | 1266 } |
| 1267 num operator ~/(num other) { | 1267 num operator ~/(num other) { |
| 1268 if ((other is int) && (other == 0)) { | |
| 1269 throw const IntegerDivisionByZeroException(); | |
| 1270 } | |
| 1271 return other._toBigintOrDouble()._truncDivFromInteger(this); | 1268 return other._toBigintOrDouble()._truncDivFromInteger(this); |
| 1272 } | 1269 } |
| 1273 num operator %(num other) { | 1270 num operator %(num other) { |
| 1274 if ((other is int) && (other == 0)) { | |
| 1275 throw const IntegerDivisionByZeroException(); | |
| 1276 } | |
| 1277 return other._toBigintOrDouble()._moduloFromInteger(this); | 1271 return other._toBigintOrDouble()._moduloFromInteger(this); |
| 1278 } | 1272 } |
| 1279 int operator &(int other) { | 1273 int operator &(int other) { |
| 1280 return other._toBigintOrDouble()._bitAndFromInteger(this); | 1274 return other._toBigintOrDouble()._bitAndFromInteger(this); |
| 1281 } | 1275 } |
| 1282 int operator |(int other) { | 1276 int operator |(int other) { |
| 1283 return other._toBigintOrDouble()._bitOrFromInteger(this); | 1277 return other._toBigintOrDouble()._bitOrFromInteger(this); |
| 1284 } | 1278 } |
| 1285 int operator ^(int other) { | 1279 int operator ^(int other) { |
| 1286 return other._toBigintOrDouble()._bitXorFromInteger(this); | 1280 return other._toBigintOrDouble()._bitXorFromInteger(this); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 int _addFromInteger(int other) { | 1355 int _addFromInteger(int other) { |
| 1362 return other._toBigint()._add(this)._toValidInt(); | 1356 return other._toBigint()._add(this)._toValidInt(); |
| 1363 } | 1357 } |
| 1364 int _subFromInteger(int other) { | 1358 int _subFromInteger(int other) { |
| 1365 return other._toBigint()._sub(this)._toValidInt(); | 1359 return other._toBigint()._sub(this)._toValidInt(); |
| 1366 } | 1360 } |
| 1367 int _mulFromInteger(int other) { | 1361 int _mulFromInteger(int other) { |
| 1368 return other._toBigint()._mul(this)._toValidInt(); | 1362 return other._toBigint()._mul(this)._toValidInt(); |
| 1369 } | 1363 } |
| 1370 int _truncDivFromInteger(int other) { | 1364 int _truncDivFromInteger(int other) { |
| 1365 if (_used == 0) { |
| 1366 throw const IntegerDivisionByZeroException(); |
| 1367 } |
| 1371 return other._toBigint()._div(this)._toValidInt(); | 1368 return other._toBigint()._div(this)._toValidInt(); |
| 1372 } | 1369 } |
| 1373 int _moduloFromInteger(int other) { | 1370 int _moduloFromInteger(int other) { |
| 1371 if (_used == 0) { |
| 1372 throw const IntegerDivisionByZeroException(); |
| 1373 } |
| 1374 _Bigint result = other._toBigint()._rem(this); | 1374 _Bigint result = other._toBigint()._rem(this); |
| 1375 if (result._neg) { | 1375 if (result._neg) { |
| 1376 if (_neg) { | 1376 if (_neg) { |
| 1377 result = result._sub(this); | 1377 result = result._sub(this); |
| 1378 } else { | 1378 } else { |
| 1379 result = result._add(this); | 1379 result = result._add(this); |
| 1380 } | 1380 } |
| 1381 } | 1381 } |
| 1382 return result._toValidInt(); | 1382 return result._toValidInt(); |
| 1383 } | 1383 } |
| 1384 int _remainderFromInteger(int other) { | 1384 int _remainderFromInteger(int other) { |
| 1385 if (_used == 0) { |
| 1386 throw const IntegerDivisionByZeroException(); |
| 1387 } |
| 1385 return other._toBigint()._rem(this)._toValidInt(); | 1388 return other._toBigint()._rem(this)._toValidInt(); |
| 1386 } | 1389 } |
| 1387 bool _greaterThanFromInteger(int other) { | 1390 bool _greaterThanFromInteger(int other) { |
| 1388 return other._toBigint()._compare(this) > 0; | 1391 return other._toBigint()._compare(this) > 0; |
| 1389 } | 1392 } |
| 1390 bool _equalToInteger(int other) { | 1393 bool _equalToInteger(int other) { |
| 1391 return other._toBigint()._compare(this) == 0; | 1394 return other._toBigint()._compare(this) == 0; |
| 1392 } | 1395 } |
| 1393 | 1396 |
| 1394 // Returns pow(this, e) % m, with e >= 0, m > 0. | 1397 // Returns pow(this, e) % m, with e >= 0, m > 0. |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 r2_used = t_used; | 1530 r2_used = t_used; |
| 1528 if (--i < 0) { | 1531 if (--i < 0) { |
| 1529 i = _DIGIT_BITS - 1; | 1532 i = _DIGIT_BITS - 1; |
| 1530 --j; | 1533 --j; |
| 1531 } | 1534 } |
| 1532 } | 1535 } |
| 1533 } | 1536 } |
| 1534 assert(!is1); | 1537 assert(!is1); |
| 1535 return z._revert(r_digits, r_used)._toValidInt(); | 1538 return z._revert(r_digits, r_used)._toValidInt(); |
| 1536 } | 1539 } |
| 1540 |
| 1541 // Returns 1/this % m, with m > 0. |
| 1542 int modInverse(int m) { |
| 1543 if (m is! int) throw new ArgumentError(m); |
| 1544 if (m <= 0) throw new RangeError(m); |
| 1545 m = m._toBigint(); |
| 1546 // TODO(regis): Implement modInverse for an even modulus. |
| 1547 if (m.isEven) throw new UnimplementedError(); |
| 1548 var t = this; |
| 1549 if ((t._compare(m) >= 0) || t._neg) { |
| 1550 t %= m; |
| 1551 t = t._toBigint(); |
| 1552 } |
| 1553 final t_used = t._used; |
| 1554 if (t_used == 0) { |
| 1555 return 0; // No inverse. |
| 1556 } |
| 1557 final m_digits = m._digits; |
| 1558 final m_used = m._used; |
| 1559 final uv_len = m_used + (m_used & 1); |
| 1560 var v_digits = _cloneDigits(t._digits, 0, t_used, uv_len); |
| 1561 var u_digits = _cloneDigits(m_digits, 0, m_used, uv_len); |
| 1562 |
| 1563 // Variables b and d require one more digit for carry. |
| 1564 final bd_used = m_used + 1; |
| 1565 final bd_len = bd_used + (bd_used & 1); |
| 1566 var b_digits = new Uint32List(bd_len); |
| 1567 var d_digits = new Uint32List(bd_len); |
| 1568 bool b_neg = false; |
| 1569 bool d_neg = false; |
| 1570 |
| 1571 d_digits[0] = 1; |
| 1572 |
| 1573 while (true) { |
| 1574 while ((u_digits[0] & 1) == 0) { |
| 1575 _rsh(u_digits, m_used, 1, u_digits); |
| 1576 if ((b_digits[0] & 1) == 1) { |
| 1577 _absSub(m_digits, m_used, b_digits, m_used, b_digits); |
| 1578 b_neg = !b_neg; |
| 1579 } |
| 1580 _rsh(b_digits, m_used, 1, b_digits); |
| 1581 } |
| 1582 while ((v_digits[0] & 1) == 0) { |
| 1583 _rsh(v_digits, m_used, 1, v_digits); |
| 1584 if ((d_digits[0] & 1) == 1) { |
| 1585 _absSub(m_digits, m_used, d_digits, m_used, d_digits); |
| 1586 d_neg = !d_neg; |
| 1587 } |
| 1588 _rsh(d_digits, m_used, 1, d_digits); |
| 1589 } |
| 1590 if (_compareDigits(u_digits, m_used, v_digits, m_used) >= 0) { |
| 1591 _absSub(u_digits, m_used, v_digits, m_used, u_digits); |
| 1592 if (b_neg == d_neg) { |
| 1593 if (_compareDigits(b_digits, m_used, d_digits, m_used) >= 0) { |
| 1594 _absSub(b_digits, m_used, d_digits, m_used, b_digits); |
| 1595 } else { |
| 1596 _absSub(d_digits, m_used, b_digits, m_used, b_digits); |
| 1597 b_neg = !b_neg; |
| 1598 } |
| 1599 } else { |
| 1600 _absAdd(b_digits, m_used, d_digits, m_used, b_digits); |
| 1601 if ((b_digits[m_used] > 0) || |
| 1602 (_compareDigits(b_digits, m_used, m_digits, m_used) > 0)) { |
| 1603 _absSub(b_digits, bd_used, m_digits, m_used, b_digits); |
| 1604 } |
| 1605 } |
| 1606 } else { |
| 1607 _absSub(v_digits, m_used, u_digits, m_used, v_digits); |
| 1608 if (b_neg == d_neg) { |
| 1609 if (_compareDigits(d_digits, m_used, b_digits, m_used) >= 0) { |
| 1610 _absSub(d_digits, m_used, b_digits, m_used, d_digits); |
| 1611 } else { |
| 1612 _absSub(b_digits, m_used, d_digits, m_used, d_digits); |
| 1613 d_neg = !d_neg; |
| 1614 } |
| 1615 } else { |
| 1616 _absAdd(d_digits, m_used, b_digits, m_used, d_digits); |
| 1617 if ((d_digits[m_used] > 0) || |
| 1618 (_compareDigits(d_digits, m_used, m_digits, m_used) > 0)) { |
| 1619 _absSub(d_digits, bd_used, m_digits, m_used, d_digits); |
| 1620 } |
| 1621 } |
| 1622 } |
| 1623 // Exit loop if u == 0. |
| 1624 var i = m_used; |
| 1625 while ((i > 0) && (u_digits[i - 1] == 0)) { |
| 1626 --i; |
| 1627 } |
| 1628 if (i == 0) break; |
| 1629 } |
| 1630 // No inverse if v != 1. |
| 1631 for (var i = m_used - 1; i > 0; --i) { |
| 1632 if (v_digits[i] != 0) return 0; // No inverse. |
| 1633 } |
| 1634 if (v_digits[0] != 1) return 0; // No inverse. |
| 1635 |
| 1636 if (d_neg) { |
| 1637 _absSub(m_digits, m_used, d_digits, m_used, d_digits); |
| 1638 } |
| 1639 return new _Bigint(false, m_used, d_digits)._toValidInt(); |
| 1640 } |
| 1537 } | 1641 } |
| 1538 | 1642 |
| 1539 // Interface for modular reduction. | 1643 // Interface for modular reduction. |
| 1540 class _Reduction { | 1644 class _Reduction { |
| 1541 // Return the number of digits used by r_digits. | 1645 // Return the number of digits used by r_digits. |
| 1542 int _convert(_Bigint x, Uint32List r_digits); | 1646 int _convert(_Bigint x, Uint32List r_digits); |
| 1543 int _mul(Uint32List x_digits, int x_used, | 1647 int _mul(Uint32List x_digits, int x_used, |
| 1544 Uint32List y_digits, int y_used, Uint32List r_digits); | 1648 Uint32List y_digits, int y_used, Uint32List r_digits); |
| 1545 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits); | 1649 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits); |
| 1546 | 1650 |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 | 1907 |
| 1804 int _mul(Uint32List x_digits, int x_used, | 1908 int _mul(Uint32List x_digits, int x_used, |
| 1805 Uint32List y_digits, int y_used, | 1909 Uint32List y_digits, int y_used, |
| 1806 Uint32List r_digits) { | 1910 Uint32List r_digits) { |
| 1807 var r_used = _Bigint._mulDigits(x_digits, x_used, | 1911 var r_used = _Bigint._mulDigits(x_digits, x_used, |
| 1808 y_digits, y_used, | 1912 y_digits, y_used, |
| 1809 r_digits); | 1913 r_digits); |
| 1810 return _reduce(r_digits, r_used); | 1914 return _reduce(r_digits, r_used); |
| 1811 } | 1915 } |
| 1812 } | 1916 } |
| OLD | NEW |