Chromium Code Reviews| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 // Allocate extra digits so the bigint can be reused. | 51 // Allocate extra digits so the bigint can be reused. |
| 52 static const int EXTRA_DIGITS = 4; | 52 static const int EXTRA_DIGITS = 4; |
| 53 | 53 |
| 54 // Min and max of non bigint values. | 54 // Min and max of non bigint values. |
| 55 static const int MIN_INT64 = (-1) << 63; | 55 static const int MIN_INT64 = (-1) << 63; |
| 56 static const int MAX_INT64 = 0x7fffffffffffffff; | 56 static const int MAX_INT64 = 0x7fffffffffffffff; |
| 57 | 57 |
| 58 // Bigint constant values. | 58 // Bigint constant values. |
| 59 // 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 |
| 60 // constants to be in canonical form (Smi). | 60 // constants to be in canonical form (Smi). |
| 61 static _Bigint ONE = new _Bigint()._setInt(1); | 61 static _Bigint ONE = new _Bigint._fromInt(1); |
| 62 | 62 |
| 63 // Digit conversion table for parsing. | 63 // Digit conversion table for parsing. |
| 64 static final Map<int, int> DIGIT_TABLE = _createDigitTable(); | 64 static final Map<int, int> DIGIT_TABLE = _createDigitTable(); |
| 65 | 65 |
| 66 // Internal data structure. | 66 // Internal data structure. |
| 67 // TODO(regis): Remove the 3 native setters below and provide a constructor | |
| 68 // taking all 3 field values, which is equivalent to making the fields final. | |
| 67 bool get _neg native "Bigint_getNeg"; | 69 bool get _neg native "Bigint_getNeg"; |
| 68 void set _neg(bool value) native "Bigint_setNeg"; | 70 void set _neg(bool value) native "Bigint_setNeg"; |
| 69 int get _used native "Bigint_getUsed"; | 71 int get _used native "Bigint_getUsed"; |
| 70 void set _used(int value) native "Bigint_setUsed"; | 72 void set _used(int value) native "Bigint_setUsed"; |
| 71 Uint32List get _digits native "Bigint_getDigits"; | 73 Uint32List get _digits native "Bigint_getDigits"; |
| 72 void set _digits(Uint32List value) native "Bigint_setDigits"; | 74 void set _digits(Uint32List value) native "Bigint_setDigits"; |
| 73 | 75 |
| 74 // Factory returning an instance initialized to value 0. | 76 // Factory returning an instance initialized to value 0. |
| 75 factory _Bigint() native "Bigint_allocate"; | 77 factory _Bigint() native "Bigint_allocate"; |
| 76 | 78 |
| 77 // Factory returning an instance initialized to an integer value. | 79 // Factory returning an instance initialized to an integer value no larger |
| 80 // than a Mint. | |
| 78 factory _Bigint._fromInt(int i) { | 81 factory _Bigint._fromInt(int i) { |
| 79 return new _Bigint()._setInt(i); | |
| 80 } | |
| 81 | |
| 82 // Factory returning an instance initialized to a hex string. | |
| 83 factory _Bigint._fromHex(String s) { | |
|
rmacnak
2015/01/13 21:22:43
Was this used by int.parse before? Do we have a fa
regis
2015/01/13 21:29:30
Currently, we only use a C++ version: Bigint::NewF
| |
| 84 return new _Bigint()._setHex(s); | |
| 85 } | |
| 86 | |
| 87 // Factory returning an instance initialized to a double value given by its | |
| 88 // components. | |
| 89 factory _Bigint._fromDouble(int sign, int significand, int exponent) { | |
| 90 return new _Bigint()._setDouble(sign, significand, exponent); | |
| 91 } | |
| 92 | |
| 93 // Initialize instance to the given value no larger than a Mint. | |
| 94 _Bigint _setInt(int i) { | |
| 95 assert(i is! _Bigint); | 82 assert(i is! _Bigint); |
| 96 _ensureLength(2); | 83 bool neg; |
| 97 _used = 2; | |
| 98 var l, h; | 84 var l, h; |
| 99 if (i < 0) { | 85 if (i < 0) { |
| 100 _neg = true; | 86 neg = true; |
| 101 if (i == MIN_INT64) { | 87 if (i == MIN_INT64) { |
| 102 l = 0; | 88 l = 0; |
| 103 h = 0x80000000; | 89 h = 0x80000000; |
| 104 } else { | 90 } else { |
| 105 l = (-i) & DIGIT_MASK; | 91 l = (-i) & DIGIT_MASK; |
| 106 h = (-i) >> DIGIT_BITS; | 92 h = (-i) >> DIGIT_BITS; |
| 107 } | 93 } |
| 108 } else { | 94 } else { |
| 109 _neg = false; | 95 neg = false; |
| 110 l = i & DIGIT_MASK; | 96 l = i & DIGIT_MASK; |
| 111 h = i >> DIGIT_BITS; | 97 h = i >> DIGIT_BITS; |
| 112 } | 98 } |
| 113 _digits[0] = l; | 99 var result = new _Bigint(); |
| 114 _digits[1] = h; | 100 result._ensureLength(2); |
| 115 _clamp(); | 101 result._neg = neg; |
| 116 return this; | 102 result._used = 2; |
| 117 } | 103 result._digits[0] = l; |
| 118 | 104 result._digits[1] = h; |
| 119 // Initialize instance to the given hex string. | 105 result._clamp(); |
| 120 // TODO(regis): Copy Bigint::NewFromHexCString, fewer digit accesses. | 106 return result; |
| 121 // TODO(regis): Unused. | |
| 122 _Bigint _setHex(String s) { | |
| 123 const int HEX_BITS = 4; | |
| 124 const int HEX_DIGITS_PER_DIGIT = 8; | |
| 125 var hexDigitIndex = s.length; | |
| 126 _ensureLength((hexDigitIndex + HEX_DIGITS_PER_DIGIT - 1) ~/ HEX_DIGITS_PER_D IGIT); | |
| 127 var bitIndex = 0; | |
| 128 var digits = _digits; | |
| 129 while (--hexDigitIndex >= 0) { | |
| 130 var digit = DIGIT_TABLE[s.codeUnitAt(hexDigitIndex)]; | |
| 131 if (digit = null) { | |
| 132 if (s[hexDigitIndex] == "-") _neg = true; | |
| 133 continue; // Ignore invalid digits. | |
| 134 } | |
| 135 _neg = false; // Ignore "-" if not at index 0. | |
| 136 if (bitIndex == 0) { | |
| 137 digits[_used++] = digit; | |
| 138 // TODO(regis): What if too many bad digits were ignored and | |
| 139 // _used becomes larger than _digits.length? error or reallocate? | |
| 140 } else { | |
| 141 digits[_used - 1] |= digit << bitIndex; | |
| 142 } | |
| 143 bitIndex = (bitIndex + HEX_BITS) % DIGIT_BITS; | |
| 144 } | |
| 145 _clamp(); | |
| 146 return this; | |
| 147 } | |
| 148 | |
| 149 // Initialize instance to the given double value. | |
| 150 _Bigint _setDouble(int sign, int significand, int exponent) { | |
| 151 assert(significand >= 0); | |
| 152 assert(exponent >= 0); | |
| 153 _setInt(significand); | |
| 154 _neg = sign < 0; | |
| 155 if (exponent > 0) { | |
| 156 _lShiftTo(exponent, this); | |
| 157 } | |
| 158 return this; | |
| 159 } | 107 } |
| 160 | 108 |
| 161 // Create digit conversion table for parsing. | 109 // Create digit conversion table for parsing. |
| 162 static Map<int, int> _createDigitTable() { | 110 static Map<int, int> _createDigitTable() { |
| 163 Map table = new HashMap(); | 111 Map table = new HashMap(); |
| 164 int digit, value; | 112 int digit, value; |
| 165 digit = "0".codeUnitAt(0); | 113 digit = "0".codeUnitAt(0); |
| 166 for(value = 0; value <= 9; ++value) table[digit++] = value; | 114 for(value = 0; value <= 9; ++value) table[digit++] = value; |
| 167 digit = "a".codeUnitAt(0); | 115 digit = "a".codeUnitAt(0); |
| 168 for(value = 10; value < 36; ++value) table[digit++] = value; | 116 for(value = 10; value < 36; ++value) table[digit++] = value; |
| (...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1298 other._toBigint()._mulTo(this, result); | 1246 other._toBigint()._mulTo(this, result); |
| 1299 return result._toValidInt(); | 1247 return result._toValidInt(); |
| 1300 } | 1248 } |
| 1301 int _truncDivFromInteger(int other) { | 1249 int _truncDivFromInteger(int other) { |
| 1302 _Bigint result = new _Bigint(); | 1250 _Bigint result = new _Bigint(); |
| 1303 other._toBigint()._divRemTo(this, result, null); | 1251 other._toBigint()._divRemTo(this, result, null); |
| 1304 return result._toValidInt(); | 1252 return result._toValidInt(); |
| 1305 } | 1253 } |
| 1306 int _moduloFromInteger(int other) { | 1254 int _moduloFromInteger(int other) { |
| 1307 _Bigint result = new _Bigint(); | 1255 _Bigint result = new _Bigint(); |
| 1308 var ob = other._toBigint(); | |
| 1309 other._toBigint()._divRemTo(this, null, result); | 1256 other._toBigint()._divRemTo(this, null, result); |
| 1310 if (result._neg) { | 1257 if (result._neg) { |
| 1311 if (_neg) { | 1258 if (_neg) { |
| 1312 result._subTo(this, result); | 1259 result._subTo(this, result); |
| 1313 } else { | 1260 } else { |
| 1314 result._addTo(this, result); | 1261 result._addTo(this, result); |
| 1315 } | 1262 } |
| 1316 } | 1263 } |
| 1317 return result._toValidInt(); | 1264 return result._toValidInt(); |
| 1318 } | 1265 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1374 z._sqrTo(g[1], g2); | 1321 z._sqrTo(g[1], g2); |
| 1375 while (n <= km) { | 1322 while (n <= km) { |
| 1376 g[n] = new _Bigint(); | 1323 g[n] = new _Bigint(); |
| 1377 z._mulTo(g2, g[n - 2], g[n]); | 1324 z._mulTo(g2, g[n - 2], g[n]); |
| 1378 n += 2; | 1325 n += 2; |
| 1379 } | 1326 } |
| 1380 } | 1327 } |
| 1381 var j = e._used - 1; | 1328 var j = e._used - 1; |
| 1382 var w; | 1329 var w; |
| 1383 var is1 = true; | 1330 var is1 = true; |
| 1384 var r = new _Bigint()._setInt(1); | 1331 var r = new _Bigint._fromInt(1); |
| 1385 var r2 = new _Bigint(); | 1332 var r2 = new _Bigint(); |
| 1386 var t; | 1333 var t; |
| 1387 var e_digits = e._digits; | 1334 var e_digits = e._digits; |
| 1388 i = _nbits(e_digits[j]) - 1; | 1335 i = _nbits(e_digits[j]) - 1; |
| 1389 while (j >= 0) { | 1336 while (j >= 0) { |
| 1390 if (i >= k1) { | 1337 if (i >= k1) { |
| 1391 w = (e_digits[j] >> (i - k1)) & km; | 1338 w = (e_digits[j] >> (i - k1)) & km; |
| 1392 } else { | 1339 } else { |
| 1393 w = (e_digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i); | 1340 w = (e_digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i); |
| 1394 if (j > 0) { | 1341 if (j > 0) { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1627 void _sqrTo(_Bigint x, _Bigint r) { | 1574 void _sqrTo(_Bigint x, _Bigint r) { |
| 1628 x._sqrTo(r); | 1575 x._sqrTo(r); |
| 1629 _reduce(r); | 1576 _reduce(r); |
| 1630 } | 1577 } |
| 1631 | 1578 |
| 1632 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { | 1579 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { |
| 1633 x._mulTo(y, r); | 1580 x._mulTo(y, r); |
| 1634 _reduce(r); | 1581 _reduce(r); |
| 1635 } | 1582 } |
| 1636 } | 1583 } |
| OLD | NEW |