| 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 28 matching lines...) Expand all Loading... |
| 39 */ | 39 */ |
| 40 | 40 |
| 41 class _Bigint extends _IntegerImplementation implements int { | 41 class _Bigint extends _IntegerImplementation implements int { |
| 42 // Bits per digit. | 42 // Bits per digit. |
| 43 static const int DIGIT_BITS = 32; | 43 static const int DIGIT_BITS = 32; |
| 44 static const int DIGIT_BASE = 1 << DIGIT_BITS; | 44 static const int DIGIT_BASE = 1 << DIGIT_BITS; |
| 45 static const int DIGIT_MASK = (1 << DIGIT_BITS) - 1; | 45 static const int DIGIT_MASK = (1 << DIGIT_BITS) - 1; |
| 46 | 46 |
| 47 // Bits per half digit. | 47 // Bits per half digit. |
| 48 static const int DIGIT2_BITS = DIGIT_BITS >> 1; | 48 static const int DIGIT2_BITS = DIGIT_BITS >> 1; |
| 49 static const int DIGIT2_BASE = 1 << DIGIT2_BITS; | |
| 50 static const int DIGIT2_MASK = (1 << DIGIT2_BITS) - 1; | 49 static const int DIGIT2_MASK = (1 << DIGIT2_BITS) - 1; |
| 51 | 50 |
| 52 // Allocate extra digits so the bigint can be reused. | 51 // Allocate extra digits so the bigint can be reused. |
| 53 static const int EXTRA_DIGITS = 4; | 52 static const int EXTRA_DIGITS = 4; |
| 54 | 53 |
| 55 // Floating-point unit integer precision. | |
| 56 static const int FP_BITS = 52; | |
| 57 static const int FP_BASE = 1 << FP_BITS; | |
| 58 static const int FP_D1 = FP_BITS - DIGIT_BITS; | |
| 59 static const int FP_D2 = 2 * DIGIT_BITS - FP_BITS; | |
| 60 | |
| 61 // Min and max of non bigint values. | 54 // Min and max of non bigint values. |
| 62 static const int MIN_INT64 = (-1) << 63; | 55 static const int MIN_INT64 = (-1) << 63; |
| 63 static const int MAX_INT64 = 0x7fffffffffffffff; | 56 static const int MAX_INT64 = 0x7fffffffffffffff; |
| 64 | 57 |
| 65 // Bigint constant values. | 58 // Bigint constant values. |
| 66 // Note: Not declared as final in order to satisfy optimizer, which expects | 59 // Note: Not declared as final in order to satisfy optimizer, which expects |
| 67 // constants to be in canonical form (Smi). | 60 // constants to be in canonical form (Smi). |
| 68 static _Bigint ZERO = new _Bigint(); | 61 static _Bigint ZERO = new _Bigint(); |
| 69 static _Bigint ONE = new _Bigint()._setInt(1); | 62 static _Bigint ONE = new _Bigint()._setInt(1); |
| 70 | 63 |
| (...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 q._used = 0; | 833 q._used = 0; |
| 841 } | 834 } |
| 842 if (r != null) { | 835 if (r != null) { |
| 843 _copyTo(r); | 836 _copyTo(r); |
| 844 } | 837 } |
| 845 return; | 838 return; |
| 846 } | 839 } |
| 847 if (r == null) { | 840 if (r == null) { |
| 848 r = new _Bigint(); | 841 r = new _Bigint(); |
| 849 } | 842 } |
| 850 var y = new _Bigint(); | 843 var y = new _Bigint(); // Normalized modulus. |
| 851 var nsh = DIGIT_BITS - _nbits(a._digits[a._used - 1]); // normalize modulus | 844 var nsh = DIGIT_BITS - _nbits(a._digits[a._used - 1]); |
| 852 if (nsh > 0) { | 845 if (nsh > 0) { |
| 853 a._lShiftTo(nsh, y); | 846 a._lShiftTo(nsh, y); |
| 854 _lShiftTo(nsh, r); | 847 _lShiftTo(nsh, r); |
| 855 } | 848 } |
| 856 else { | 849 else { |
| 857 a._copyTo(y); | 850 a._copyTo(y); |
| 858 _copyTo(r); | 851 _copyTo(r); |
| 859 } | 852 } |
| 860 // We consider this and a positive. Ignore the copied sign. | 853 // We consider this and a positive. Ignore the copied sign. |
| 861 y._neg = false; | 854 y._neg = false; |
| 862 r._neg = false; | 855 r._neg = false; |
| 863 var y_used = y._used; | 856 var y_used = y._used; |
| 864 var y0 = y._digits[y_used - 1]; | 857 var y0 = y._digits[y_used - 1]; |
| 865 if (y0 == 0) return; | 858 if (y0 == 0) return; |
| 866 var yt = y0*(1 << FP_D1) + ((y_used > 1) ? y._digits[y_used - 2] >> FP_D2 :
0); | 859 var yt = y0 >> 1; // Chop off one bit, see below. y is normalized: yt != 0. |
| 867 var d1 = FP_BASE/yt; | |
| 868 var d2 = (1 << FP_D1)/yt; | |
| 869 var e = 1 << FP_D2; | |
| 870 var i = r._used; | 860 var i = r._used; |
| 871 var j = i - y_used; | 861 var j = i - y_used; |
| 872 _Bigint t = (q == null) ? new _Bigint() : q; | 862 _Bigint t = (q == null) ? new _Bigint() : q; |
| 873 | 863 |
| 874 y._dlShiftTo(j, t); | 864 y._dlShiftTo(j, t); |
| 875 | 865 |
| 876 if (r._compareTo(t) >= 0) { | 866 if (r._compareTo(t) >= 0) { |
| 877 r._digits[r._used++] = 1; | 867 r._digits[r._used++] = 1; |
| 878 r._subTo(t, r); | 868 r._subTo(t, r); |
| 879 } | 869 } |
| 880 ONE._dlShiftTo(y_used, t); | 870 ONE._dlShiftTo(y_used, t); |
| 881 t._subTo(y, y); // "negative" y so we can replace sub with _am later | 871 t._subTo(y, y); // Negate y so we can replace sub with _am later. |
| 882 while (y._used < y_used) { | 872 while (y._used < y_used) { |
| 883 y._digits[y._used++] = 0; | 873 y._digits[y._used++] = 0; |
| 884 } | 874 } |
| 885 while (--j >= 0) { | 875 while (--j >= 0) { |
| 886 // Estimate quotient digit | 876 // Estimate quotient digit. |
| 887 var qd = (r._digits[--i] == y0) | 877 var qd; |
| 888 ? DIGIT_MASK | 878 if (r._digits[--i] == y0) { |
| 889 : (r._digits[i]*d1 + (r._digits[i - 1] + e)*d2).floor(); | 879 qd = DIGIT_MASK; |
| 890 if ((r._digits[i] += y._amc(0, qd, r, j, 0, y_used)) < qd) { // Try it ou
t | 880 } else { |
| 881 // Chop off one bit, since a Mint cannot hold 2 DIGITs. |
| 882 qd = ((r._digits[i] << (DIGIT_BITS - 1)) | |
| 883 (r._digits[i - 1] >> 1)) ~/ yt; |
| 884 if (qd > DIGIT_MASK) { |
| 885 qd = DIGIT_MASK; |
| 886 } |
| 887 } |
| 888 if ((r._digits[i] += y._am(0, qd, r, j, y_used)) < qd) { // Try it out. |
| 891 y._dlShiftTo(j, t); | 889 y._dlShiftTo(j, t); |
| 892 r._subTo(t, r); | 890 r._subTo(t, r); |
| 893 while (r._digits[i] < --qd) { | 891 while (r._digits[i] < --qd) { |
| 894 r._subTo(t, r); | 892 r._subTo(t, r); |
| 895 } | 893 } |
| 896 } | 894 } |
| 897 } | 895 } |
| 898 if (q != null) { | 896 if (q != null) { |
| 899 r._drShiftTo(y_used, q); | 897 r._drShiftTo(y_used, q); |
| 900 if (_neg != a._neg) { | 898 if (_neg != a._neg) { |
| 901 ZERO._subTo(q, q); | 899 ZERO._subTo(q, q); |
| 902 } | 900 } |
| 903 } | 901 } |
| 904 r._used = y_used; | 902 r._used = y_used; |
| 905 r._clamp(); | 903 r._clamp(); |
| 906 if (nsh > 0) { | 904 if (nsh > 0) { |
| 907 r._rShiftTo(nsh, r); // Denormalize remainder | 905 r._rShiftTo(nsh, r); // Denormalize remainder. |
| 908 } | 906 } |
| 909 if (_neg) { | 907 if (_neg) { |
| 910 ZERO._subTo(r, r); | 908 ZERO._subTo(r, r); |
| 911 } | 909 } |
| 912 } | 910 } |
| 913 | 911 |
| 914 int get _identityHashCode { | 912 int get _identityHashCode { |
| 915 return this; | 913 return this; |
| 916 } | 914 } |
| 917 int operator ~() { | 915 int operator ~() { |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 void _sqrTo(_Bigint x, _Bigint r) { | 1345 void _sqrTo(_Bigint x, _Bigint r) { |
| 1348 x._sqrTo(r); | 1346 x._sqrTo(r); |
| 1349 _reduce(r); | 1347 _reduce(r); |
| 1350 } | 1348 } |
| 1351 | 1349 |
| 1352 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { | 1350 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { |
| 1353 x._mulTo(y, r); | 1351 x._mulTo(y, r); |
| 1354 _reduce(r); | 1352 _reduce(r); |
| 1355 } | 1353 } |
| 1356 } | 1354 } |
| OLD | NEW |