Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: runtime/lib/bigint.dart

Issue 916153002: Improve _toInt64() and _toUint64() conversions in TypedData. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/lib/typed_data.dart » ('j') | runtime/lib/typed_data.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 1160
1161 int get bitLength { 1161 int get bitLength {
1162 if (_used == 0) return 0; 1162 if (_used == 0) return 0;
1163 if (_neg) return (~this).bitLength; 1163 if (_neg) return (~this).bitLength;
1164 return _DIGIT_BITS*(_used - 1) + _nbits(_digits[_used - 1]); 1164 return _DIGIT_BITS*(_used - 1) + _nbits(_digits[_used - 1]);
1165 } 1165 }
1166 1166
1167 // This method must support smi._toBigint()._shrFromInt(int). 1167 // This method must support smi._toBigint()._shrFromInt(int).
1168 int _shrFromInt(int other) { 1168 int _shrFromInt(int other) {
1169 if (_used == 0) return other; // Shift amount is zero. 1169 if (_used == 0) return other; // Shift amount is zero.
1170 if (_neg) throw "negative shift amount"; // TODO(regis): What exception? 1170 if (_neg) throw new RangeError(this);
1171 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. 1171 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised.
1172 var shift; 1172 var shift;
1173 if ((_used > 2) || ((_used == 2) && (_digits[1] > 0x10000000))) { 1173 if ((_used > 2) || ((_used == 2) && (_digits[1] > 0x10000000))) {
1174 if (other < 0) { 1174 if (other < 0) {
1175 return -1; 1175 return -1;
1176 } else { 1176 } else {
1177 return 0; 1177 return 0;
1178 } 1178 }
1179 } else { 1179 } else {
1180 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; 1180 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0];
1181 } 1181 }
1182 return other._toBigint()._rShift(shift)._toValidInt(); 1182 return other._toBigint()._rShift(shift)._toValidInt();
1183 } 1183 }
1184 1184
1185 // This method must support smi._toBigint()._shlFromInt(int). 1185 // This method must support smi._toBigint()._shlFromInt(int).
1186 // An out of memory exception is thrown if the result cannot be allocated. 1186 // An out of memory exception is thrown if the result cannot be allocated.
1187 int _shlFromInt(int other) { 1187 int _shlFromInt(int other) {
1188 if (_used == 0) return other; // Shift amount is zero. 1188 if (_used == 0) return other; // Shift amount is zero.
1189 if (_neg) throw "negative shift amount"; // TODO(regis): What exception? 1189 if (_neg) throw new RangeError(this);
1190 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. 1190 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised.
1191 var shift; 1191 var shift;
1192 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) { 1192 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) {
1193 throw new OutOfMemoryError(); 1193 throw new OutOfMemoryError();
1194 } else { 1194 } else {
1195 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; 1195 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0];
1196 } 1196 }
1197 return other._toBigint()._lShift(shift)._toValidInt(); 1197 return other._toBigint()._lShift(shift)._toValidInt();
1198 } 1198 }
1199 1199
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 return other._toBigint()._compare(this) == 0; 1338 return other._toBigint()._compare(this) == 0;
1339 } 1339 }
1340 1340
1341 // Returns pow(this, e) % m, with e >= 0, m > 0. 1341 // Returns pow(this, e) % m, with e >= 0, m > 0.
1342 int modPow(int e, int m) { 1342 int modPow(int e, int m) {
1343 if (e is! int) throw new ArgumentError(e); 1343 if (e is! int) throw new ArgumentError(e);
1344 if (m is! int) throw new ArgumentError(m); 1344 if (m is! int) throw new ArgumentError(m);
1345 if (e < 0) throw new RangeError(e); 1345 if (e < 0) throw new RangeError(e);
1346 if (m <= 0) throw new RangeError(m); 1346 if (m <= 0) throw new RangeError(m);
1347 if (e == 0) return 1; 1347 if (e == 0) return 1;
1348 e = e._toBigint();
1349 m = m._toBigint();
1348 final m_used = m._used; 1350 final m_used = m._used;
1349 final m_used2p2 = 2*m_used + 1 + 1; // +1 for leading zero. 1351 final m_used2p2 = 2*m_used + 2;
1350 final e_bitlen = e.bitLength; 1352 final e_bitlen = e.bitLength;
1351 if (e_bitlen <= 0) return 1; 1353 if (e_bitlen <= 0) return 1;
1352 if ((e is! _Bigint) || m.isEven) { 1354 if ((e is! _Bigint) || m.isEven) {
1353 _Reduction z = (e_bitlen < 8 || m.isEven) ? 1355 _Reduction z = (e_bitlen < 8 || m.isEven) ?
1354 new _Classic(m) : new _Montgomery(m); 1356 new _Classic(m) : new _Montgomery(m);
1355 // TODO(regis): Should we use Barrett reduction for an even modulus? 1357 // TODO(regis): Should we use Barrett reduction for an even modulus?
1356 var m_used = m._used;
1357 var r_digits = new Uint32List(m_used2p2); 1358 var r_digits = new Uint32List(m_used2p2);
1358 var r2_digits = new Uint32List(m_used2p2); 1359 var r2_digits = new Uint32List(m_used2p2);
1359 var g_digits = new Uint32List(m_used + (m_used & 1)); 1360 var g_digits = new Uint32List(m_used + (m_used & 1));
1360 var g_used = z._convert(this, g_digits); 1361 var g_used = z._convert(this, g_digits);
1361 // Initialize r with g. 1362 // Initialize r with g.
1362 var j = g_used + (g_used & 1); // Copy leading zero if any. 1363 var j = g_used + (g_used & 1); // Copy leading zero if any.
1363 while (--j >= 0) { 1364 while (--j >= 0) {
1364 r_digits[j] = g_digits[j]; 1365 r_digits[j] = g_digits[j];
1365 } 1366 }
1366 var r_used = g_used; 1367 var r_used = g_used;
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1623 var d = _mulMod(_args, x_digits, i); 1624 var d = _mulMod(_args, x_digits, i);
1624 assert(d == _digits_per_step); 1625 assert(d == _digits_per_step);
1625 d = _Bigint._mulAdd(_args, _MU, m_digits, 0, x_digits, i, m_used); 1626 d = _Bigint._mulAdd(_args, _MU, m_digits, 0, x_digits, i, m_used);
1626 assert(d == _digits_per_step); 1627 assert(d == _digits_per_step);
1627 i += d; 1628 i += d;
1628 } 1629 }
1629 // Clamp x. 1630 // Clamp x.
1630 while (x_used > 0 && x_digits[x_used - 1] == 0) { 1631 while (x_used > 0 && x_digits[x_used - 1] == 0) {
1631 --x_used; 1632 --x_used;
1632 } 1633 }
1633 x_used = _Bigint._drShiftDigits(x_digits, x_used, m_used, x_digits); 1634 // Shift right by m_used digits or, if processing pairs, by i (even) digits.
1635 x_used = _Bigint._drShiftDigits(x_digits, x_used, i, x_digits);
1634 if (_Bigint._compareDigits(x_digits, x_used, m_digits, m_used) >= 0) { 1636 if (_Bigint._compareDigits(x_digits, x_used, m_digits, m_used) >= 0) {
1635 _Bigint._absSub(x_digits, x_used, m_digits, m_used, x_digits); 1637 _Bigint._absSub(x_digits, x_used, m_digits, m_used, x_digits);
1636 } 1638 }
1637 // Clamp x. 1639 // Clamp x.
1638 while (x_used > 0 && x_digits[x_used - 1] == 0) { 1640 while (x_used > 0 && x_digits[x_used - 1] == 0) {
1639 --x_used; 1641 --x_used;
1640 } 1642 }
1641 return x_used; 1643 return x_used;
1642 } 1644 }
1643 1645
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 // _neg_norm_m_digits is read-only and has nm_used digits (possibly 1695 // _neg_norm_m_digits is read-only and has nm_used digits (possibly
1694 // including several leading zeros) plus a leading zero for 64-bit 1696 // including several leading zeros) plus a leading zero for 64-bit
1695 // processing. 1697 // processing.
1696 _t_digits = new Uint32List(2*nm_used); 1698 _t_digits = new Uint32List(2*nm_used);
1697 } 1699 }
1698 1700
1699 int _convert(_Bigint x, Uint32List r_digits) { 1701 int _convert(_Bigint x, Uint32List r_digits) {
1700 var digits; 1702 var digits;
1701 var used; 1703 var used;
1702 if (x._neg || x._compare(_m) >= 0) { 1704 if (x._neg || x._compare(_m) >= 0) {
1703 var r = x.rem(_m); 1705 var r = x._rem(_m);
1704 if (x._neg && !r._neg && r._used > 0) { 1706 if (x._neg && !r._neg && r._used > 0) {
1705 r = _m._sub(r); 1707 r = _m._sub(r);
1706 } 1708 }
1707 assert(!r._neg); 1709 assert(!r._neg);
1708 used = r._used; 1710 used = r._used;
1709 digits = r._digits; 1711 digits = r._digits;
1710 } else { 1712 } else {
1711 used = x._used; 1713 used = x._used;
1712 digits = x._digits; 1714 digits = x._digits;
1713 } 1715 }
1714 var i = used + (used + 1); // Copy leading zero if any. 1716 var i = used + (used & 1); // Copy leading zero if any.
1715 while (--i >= 0) { 1717 while (--i >= 0) {
1716 r_digits[i] = digits[i]; 1718 r_digits[i] = digits[i];
1717 } 1719 }
1718 return used; 1720 return used;
1719 } 1721 }
1720 1722
1721 _Bigint _revert(Uint32List x_digits, int x_used) { 1723 _Bigint _revert(Uint32List x_digits, int x_used) {
1722 return new _Bigint(false, x_used, x_digits); 1724 return new _Bigint(false, x_used, x_digits);
1723 } 1725 }
1724 1726
(...skipping 16 matching lines...) Expand all
1741 1743
1742 int _mul(Uint32List x_digits, int x_used, 1744 int _mul(Uint32List x_digits, int x_used,
1743 Uint32List y_digits, int y_used, 1745 Uint32List y_digits, int y_used,
1744 Uint32List r_digits) { 1746 Uint32List r_digits) {
1745 var r_used = _Bigint._mulDigits(x_digits, x_used, 1747 var r_used = _Bigint._mulDigits(x_digits, x_used,
1746 y_digits, y_used, 1748 y_digits, y_used,
1747 r_digits); 1749 r_digits);
1748 return _reduce(r_digits, r_used); 1750 return _reduce(r_digits, r_used);
1749 } 1751 }
1750 } 1752 }
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/typed_data.dart » ('j') | runtime/lib/typed_data.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698