| 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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 int l = m_digits[i] & DIGIT2_MASK; | 808 int l = m_digits[i] & DIGIT2_MASK; |
| 809 int h = m_digits[i++] >> DIGIT2_BITS; | 809 int h = m_digits[i++] >> DIGIT2_BITS; |
| 810 int m = xh*l + h*xl; | 810 int m = xh*l + h*xl; |
| 811 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + a_digits[j] + c; | 811 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + a_digits[j] + c; |
| 812 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; | 812 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; |
| 813 a_digits[j++] = l & DIGIT_MASK; | 813 a_digits[j++] = l & DIGIT_MASK; |
| 814 } | 814 } |
| 815 args[MA_CARRY_OUT] = c; | 815 args[MA_CARRY_OUT] = c; |
| 816 } | 816 } |
| 817 | 817 |
| 818 // Square and accumulate. | 818 // Multiply and accumulate with carry in. |
| 819 // Input: | 819 // Input: |
| 820 // x_digits[i..used-1]: digits of operand being squared. | 820 // x: multiplier digit, 0 <= x < 2*DIGIT_BASE (i.e. 33-bit multiplier). |
| 821 // a_digits[2*i..i+used-1]: accumulator digits. | 821 // m_digits[i..i+n-1]: multiplicand digits. |
| 822 // a_digits[j..j+n-1]: accumulator digits. |
| 823 // c: carry in. |
| 822 // Operation: | 824 // Operation: |
| 823 // a_digits[2*i..i+used-1] += x_digits[i]*x_digits[i] + | 825 // a_digits[j..j+n-1] += x*m_digits[i..i+n-1] + c. |
| 824 // 2*x_digits[i]*x_digits[i+1..used-1]. | 826 // Output: |
| 825 static void _sqrAdd(Uint32List x_digits, int i, | 827 // carry out. |
| 826 Uint32List a_digits, int used) { | 828 // TODO(regis): Use an argument buffer as in _mulAdd. |
| 827 int x = x_digits[i]; | 829 static int _mulAddc(int x, Uint32List m_digits, int i, |
| 828 if (x == 0) return; | 830 Uint32List a_digits, int j, int c, int n) { |
| 829 int j = 2*i; | 831 if (x == 0 && c == 0) { |
| 830 int c = 0; | 832 // No-op if both x and c are 0. |
| 833 return 0; |
| 834 } |
| 831 int xl = x & DIGIT2_MASK; | 835 int xl = x & DIGIT2_MASK; |
| 832 int xh = x >> DIGIT2_BITS; | 836 int xh = x >> DIGIT2_BITS; |
| 833 int m = 2*xh*xl; | |
| 834 int l = xl*xl + ((m & DIGIT2_MASK) << DIGIT2_BITS) + a_digits[j]; | |
| 835 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*xh; | |
| 836 a_digits[j] = l & DIGIT_MASK; | |
| 837 x <<= 1; | |
| 838 xl = x & DIGIT2_MASK; | |
| 839 xh = x >> DIGIT2_BITS; | |
| 840 int n = used - i - 1; | |
| 841 int k = i + 1; | |
| 842 j++; | |
| 843 while (--n >= 0) { | 837 while (--n >= 0) { |
| 844 int l = x_digits[k] & DIGIT2_MASK; | 838 int l = m_digits[i] & DIGIT2_MASK; |
| 845 int h = x_digits[k++] >> DIGIT2_BITS; | 839 int h = m_digits[i++] >> DIGIT2_BITS; |
| 846 int m = xh*l + h*xl; | 840 int m = xh*l + h*xl; |
| 847 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + a_digits[j] + c; | 841 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + a_digits[j] + c; |
| 848 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; | 842 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; |
| 849 a_digits[j++] = l & DIGIT_MASK; | 843 a_digits[j++] = l & DIGIT_MASK; |
| 850 } | 844 } |
| 851 c += a_digits[i + used]; | 845 return c; |
| 852 if (c >= DIGIT_BASE) { | |
| 853 a_digits[i + used] = c - DIGIT_BASE; | |
| 854 a_digits[i + used + 1] = 1; | |
| 855 } else { | |
| 856 a_digits[i + used] = c; | |
| 857 } | |
| 858 } | 846 } |
| 859 | 847 |
| 860 // r = this * a. | 848 // r = this * a. |
| 861 void _mulTo(_Bigint a, _Bigint r) { | 849 void _mulTo(_Bigint a, _Bigint r) { |
| 862 // TODO(regis): Use karatsuba multiplication when appropriate. | 850 // TODO(regis): Use karatsuba multiplication when appropriate. |
| 863 var used = _used; | 851 var used = _used; |
| 864 var a_used = a._used; | 852 var a_used = a._used; |
| 865 var i = used; | 853 var i = used; |
| 866 r._ensureLength(i + a_used); | 854 r._ensureLength(i + a_used); |
| 867 var digits = _digits; | 855 var digits = _digits; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 885 var used = _used; | 873 var used = _used; |
| 886 var r_used = 2 * used; | 874 var r_used = 2 * used; |
| 887 r._ensureLength(r_used); | 875 r._ensureLength(r_used); |
| 888 var digits = _digits; | 876 var digits = _digits; |
| 889 var r_digits = r._digits; | 877 var r_digits = r._digits; |
| 890 var i = r_used; | 878 var i = r_used; |
| 891 while (--i >= 0) { | 879 while (--i >= 0) { |
| 892 r_digits[i] = 0; | 880 r_digits[i] = 0; |
| 893 } | 881 } |
| 894 for (i = 0; i < used - 1; ++i) { | 882 for (i = 0; i < used - 1; ++i) { |
| 895 _sqrAdd(digits, i, r_digits, used); | 883 _MulAddArgs[MA_MULTIPLIER] = digits[i]; |
| 884 _mulAdd(_MulAddArgs, digits, i, r_digits, 2*i, 1); |
| 885 var c = _MulAddArgs[MA_CARRY_OUT]; |
| 886 var d = r_digits[i + used]; |
| 887 d += _mulAddc(digits[i] << 1, digits, i + 1, |
| 888 r_digits, 2*i + 1, c, used - i - 1); |
| 889 if (d >= DIGIT_BASE) { |
| 890 r_digits[i + used] = d - DIGIT_BASE; |
| 891 r_digits[i + used + 1] = 1; |
| 892 } else { |
| 893 r_digits[i + used] = d; |
| 894 } |
| 896 } | 895 } |
| 897 if (r_used > 0) { | 896 if (r_used > 0) { |
| 898 _MulAddArgs[MA_MULTIPLIER] = digits[i]; | 897 _MulAddArgs[MA_MULTIPLIER] = digits[i]; |
| 899 _mulAdd(_MulAddArgs, digits, i, r_digits, 2*i, 1); | 898 _mulAdd(_MulAddArgs, digits, i, r_digits, 2*i, 1); |
| 900 r_digits[r_used - 1] += _MulAddArgs[MA_CARRY_OUT]; | 899 r_digits[r_used - 1] += _MulAddArgs[MA_CARRY_OUT]; |
| 901 } | 900 } |
| 902 r._used = r_used; | 901 r._used = r_used; |
| 903 r._neg = false; | 902 r._neg = false; |
| 904 r._clamp(); | 903 r._clamp(); |
| 905 } | 904 } |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 void _sqrTo(_Bigint x, _Bigint r) { | 1438 void _sqrTo(_Bigint x, _Bigint r) { |
| 1440 x._sqrTo(r); | 1439 x._sqrTo(r); |
| 1441 _reduce(r); | 1440 _reduce(r); |
| 1442 } | 1441 } |
| 1443 | 1442 |
| 1444 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { | 1443 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { |
| 1445 x._mulTo(y, r); | 1444 x._mulTo(y, r); |
| 1446 _reduce(r); | 1445 _reduce(r); |
| 1447 } | 1446 } |
| 1448 } | 1447 } |
| OLD | NEW |