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 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 } | 287 } |
288 | 288 |
289 // Return this << n. | 289 // Return this << n. |
290 _Bigint _lShift(int n) { | 290 _Bigint _lShift(int n) { |
291 final ds = n ~/ _DIGIT_BITS; | 291 final ds = n ~/ _DIGIT_BITS; |
292 final bs = n % _DIGIT_BITS; | 292 final bs = n % _DIGIT_BITS; |
293 if (bs == 0) { | 293 if (bs == 0) { |
294 return _dlShift(ds); | 294 return _dlShift(ds); |
295 } | 295 } |
296 var r_used = _used + ds + 1; | 296 var r_used = _used + ds + 1; |
297 var r_digits = new Uint32List(r_used + 2 + (r_used & 1)); // +2 for 64-bit. | 297 var r_digits = new Uint32List(r_used + 2 - (r_used & 1)); // for 64-bit. |
298 _lsh(_digits, _used, n, r_digits); | 298 _lsh(_digits, _used, n, r_digits); |
299 return new _Bigint(_neg, r_used, r_digits); | 299 return new _Bigint(_neg, r_used, r_digits); |
300 } | 300 } |
301 | 301 |
302 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. | 302 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. |
303 // Return r_used. | 303 // Return r_used. |
304 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, | 304 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, |
305 Uint32List r_digits) { | 305 Uint32List r_digits) { |
306 final ds = n ~/ _DIGIT_BITS; | 306 final ds = n ~/ _DIGIT_BITS; |
307 final bs = n % _DIGIT_BITS; | 307 final bs = n % _DIGIT_BITS; |
308 if (bs == 0) { | 308 if (bs == 0) { |
309 return _dlShiftDigits(x_digits, x_used, ds, r_digits); | 309 return _dlShiftDigits(x_digits, x_used, ds, r_digits); |
310 } | 310 } |
311 var r_used = x_used + ds + 1; | 311 var r_used = x_used + ds + 1; |
312 assert(r_digits.length >= r_used + 2 + (r_used & 1)); // +2 for 64-bit. | 312 assert(r_digits.length >= r_used + 2 - (r_used & 1)); // for 64-bit. |
313 _lsh(x_digits, x_used, n, r_digits); | 313 _lsh(x_digits, x_used, n, r_digits); |
314 var i = ds; | 314 var i = ds; |
315 while (--i >= 0) { | 315 while (--i >= 0) { |
316 r_digits[i] = 0; | 316 r_digits[i] = 0; |
317 } | 317 } |
318 if (r_digits[r_used - 1] == 0) { | 318 if (r_digits[r_used - 1] == 0) { |
319 r_used--; // Clamp result. | 319 r_used--; // Clamp result. |
320 } else if (r_used.isOdd) { | 320 } else if (r_used.isOdd) { |
321 r_digits[r_used] = 0; | 321 r_digits[r_used] = 0; |
322 } | 322 } |
(...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 if ((y_digits[0] & 1) == 1) { | 1578 if ((y_digits[0] & 1) == 1) { |
1579 var t_digits = x_digits; | 1579 var t_digits = x_digits; |
1580 var t_used = x_used; | 1580 var t_used = x_used; |
1581 x_digits = y_digits; | 1581 x_digits = y_digits; |
1582 x_used = y_used; | 1582 x_used = y_used; |
1583 y_digits = t_digits; | 1583 y_digits = t_digits; |
1584 y_used = t_used; | 1584 y_used = t_used; |
1585 } | 1585 } |
1586 } | 1586 } |
1587 var u_digits = _cloneDigits(x_digits, 0, x_used, m_len); | 1587 var u_digits = _cloneDigits(x_digits, 0, x_used, m_len); |
1588 var v_digits = _cloneDigits(y_digits, 0, y_used, m_len); | 1588 var v_digits = _cloneDigits(y_digits, 0, y_used, m_len + 2); // +2 for lsh. |
1589 final bool ac = (x_digits[0] & 1) == 0; | 1589 final bool ac = (x_digits[0] & 1) == 0; |
1590 | 1590 |
1591 // Variables a, b, c, and d require one more digit. | 1591 // Variables a, b, c, and d require one more digit. |
1592 final abcd_used = m_used + 1; | 1592 final abcd_used = m_used + 1; |
1593 final abcd_len = abcd_used + (abcd_used & 1) + 2; // +2 to satisfy _absAdd. | 1593 final abcd_len = abcd_used + (abcd_used & 1) + 2; // +2 to satisfy _absAdd. |
1594 var a_digits, b_digits, c_digits, d_digits; | 1594 var a_digits, b_digits, c_digits, d_digits; |
1595 bool a_neg, b_neg, c_neg, d_neg; | 1595 bool a_neg, b_neg, c_neg, d_neg; |
1596 if (ac) { | 1596 if (ac) { |
1597 a_digits = new Uint32List(abcd_len); | 1597 a_digits = new Uint32List(abcd_len); |
1598 a_neg = false; | 1598 a_neg = false; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 } else { | 1741 } else { |
1742 _absAdd(d_digits, abcd_used, b_digits, abcd_used, d_digits); | 1742 _absAdd(d_digits, abcd_used, b_digits, abcd_used, d_digits); |
1743 } | 1743 } |
1744 } | 1744 } |
1745 // Exit loop if u == 0. | 1745 // Exit loop if u == 0. |
1746 var i = m_used; | 1746 var i = m_used; |
1747 while ((i > 0) && (u_digits[i - 1] == 0)) --i; | 1747 while ((i > 0) && (u_digits[i - 1] == 0)) --i; |
1748 if (i == 0) break; | 1748 if (i == 0) break; |
1749 } | 1749 } |
1750 if (!inv) { | 1750 if (!inv) { |
1751 // TODO(regis): Make this work correctly: | 1751 if (s > 0) { |
1752 // if (s > 0) { | 1752 m_used = _lShiftDigits(v_digits, m_used, s, v_digits); |
1753 // m_used = _dlShiftDigits(v_digits, m_used, s, v_digits); | 1753 } |
1754 // } | 1754 return new _Bigint(false, m_used, v_digits)._toValidInt(); |
1755 return new _Bigint(false, m_used, v_digits)._toValidInt() << s; | |
1756 } | 1755 } |
1757 // No inverse if v != 1. | 1756 // No inverse if v != 1. |
1758 var i = m_used - 1; | 1757 var i = m_used - 1; |
1759 while ((i > 0) && (v_digits[i] == 0)) --i; | 1758 while ((i > 0) && (v_digits[i] == 0)) --i; |
1760 if ((i != 0) || (v_digits[0] != 1)) throw new RangeError("Not coprime"); | 1759 if ((i != 0) || (v_digits[0] != 1)) throw new RangeError("Not coprime"); |
1761 | 1760 |
1762 if (d_neg) { | 1761 if (d_neg) { |
1763 if ((d_digits[m_used] != 0) || | 1762 if ((d_digits[m_used] != 0) || |
1764 (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) { | 1763 (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) { |
1765 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits); | 1764 _absSub(d_digits, abcd_used, x_digits, m_used, d_digits); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2073 | 2072 |
2074 int _mul(Uint32List x_digits, int x_used, | 2073 int _mul(Uint32List x_digits, int x_used, |
2075 Uint32List y_digits, int y_used, | 2074 Uint32List y_digits, int y_used, |
2076 Uint32List r_digits) { | 2075 Uint32List r_digits) { |
2077 var r_used = _Bigint._mulDigits(x_digits, x_used, | 2076 var r_used = _Bigint._mulDigits(x_digits, x_used, |
2078 y_digits, y_used, | 2077 y_digits, y_used, |
2079 r_digits); | 2078 r_digits); |
2080 return _reduce(r_digits, r_used); | 2079 return _reduce(r_digits, r_used); |
2081 } | 2080 } |
2082 } | 2081 } |
OLD | NEW |