| 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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 return _dlShift(ds); | 264 return _dlShift(ds); |
| 265 } | 265 } |
| 266 var cbs = _DIGIT_BITS - bs; | 266 var cbs = _DIGIT_BITS - bs; |
| 267 var bm = (1 << cbs) - 1; | 267 var bm = (1 << cbs) - 1; |
| 268 var r_used = _used + ds + 1; | 268 var r_used = _used + ds + 1; |
| 269 var digits = _digits; | 269 var digits = _digits; |
| 270 var r_digits = new Uint32List(r_used + (r_used & 1)); | 270 var r_digits = new Uint32List(r_used + (r_used & 1)); |
| 271 var c = 0; | 271 var c = 0; |
| 272 var i = _used; | 272 var i = _used; |
| 273 while (--i >= 0) { | 273 while (--i >= 0) { |
| 274 r_digits[i + ds + 1] = (digits[i] >> cbs) | c; | 274 final d = digits[i]; |
| 275 c = (digits[i] & bm) << bs; | 275 r_digits[i + ds + 1] = (d >> cbs) | c; |
| 276 c = (d & bm) << bs; |
| 276 } | 277 } |
| 277 r_digits[ds] = c; | 278 r_digits[ds] = c; |
| 278 return new _Bigint(_neg, r_used, r_digits); | 279 return new _Bigint(_neg, r_used, r_digits); |
| 279 } | 280 } |
| 280 | 281 |
| 281 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. | 282 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. |
| 282 // Return r_used. | 283 // Return r_used. |
| 283 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, | 284 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, |
| 284 Uint32List r_digits) { | 285 Uint32List r_digits) { |
| 285 var ds = n ~/ _DIGIT_BITS; | 286 var ds = n ~/ _DIGIT_BITS; |
| 286 var bs = n % _DIGIT_BITS; | 287 var bs = n % _DIGIT_BITS; |
| 287 if (bs == 0) { | 288 if (bs == 0) { |
| 288 return _dlShiftDigits(x_digits, x_used, ds, r_digits); | 289 return _dlShiftDigits(x_digits, x_used, ds, r_digits); |
| 289 } | 290 } |
| 290 var cbs = _DIGIT_BITS - bs; | 291 var cbs = _DIGIT_BITS - bs; |
| 291 var bm = (1 << cbs) - 1; | 292 var bm = (1 << cbs) - 1; |
| 292 var r_used = x_used + ds + 1; | 293 var r_used = x_used + ds + 1; |
| 293 assert(r_digits.length >= r_used + (r_used & 1)); | 294 assert(r_digits.length >= r_used + (r_used & 1)); |
| 294 var c = 0; | 295 var c = 0; |
| 295 var i = x_used; | 296 var i = x_used; |
| 296 while (--i >= 0) { | 297 while (--i >= 0) { |
| 297 r_digits[i + ds + 1] = (x_digits[i] >> cbs) | c; | 298 final d = x_digits[i]; |
| 298 c = (x_digits[i] & bm) << bs; | 299 r_digits[i + ds + 1] = (d >> cbs) | c; |
| 300 c = (d & bm) << bs; |
| 299 } | 301 } |
| 300 r_digits[ds] = c; | 302 r_digits[ds] = c; |
| 301 i = ds; | 303 i = ds; |
| 302 while (--i >= 0) { | 304 while (--i >= 0) { |
| 303 r_digits[i] = 0; | 305 r_digits[i] = 0; |
| 304 } | 306 } |
| 305 if (r_used.isOdd) { | 307 if (r_digits[r_used - 1] == 0) { |
| 308 r_used--; // Clamp result. |
| 309 } else if (r_used.isOdd) { |
| 306 r_digits[r_used] = 0; | 310 r_digits[r_used] = 0; |
| 307 } | 311 } |
| 308 return r_used; | 312 return r_used; |
| 309 } | 313 } |
| 310 | 314 |
| 311 // Return this >> n. | 315 // Return this >> n. |
| 312 _Bigint _rShift(int n) { | 316 _Bigint _rShift(int n) { |
| 313 var ds = n ~/ _DIGIT_BITS; | 317 var ds = n ~/ _DIGIT_BITS; |
| 314 var bs = n % _DIGIT_BITS; | 318 var bs = n % _DIGIT_BITS; |
| 315 if (bs == 0) { | 319 if (bs == 0) { |
| 316 return _drShift(ds); | 320 return _drShift(ds); |
| 317 } | 321 } |
| 318 var r_used = _used - ds; | 322 var r_used = _used - ds; |
| 319 if (r_used <= 0) { | 323 if (r_used <= 0) { |
| 320 return _neg ? _MINUS_ONE : _ZERO; | 324 return _neg ? _MINUS_ONE : _ZERO; |
| 321 } | 325 } |
| 322 var cbs = _DIGIT_BITS - bs; | 326 var cbs = _DIGIT_BITS - bs; |
| 323 var bm = (1 << bs) - 1; | 327 var bm = (1 << bs) - 1; |
| 324 var digits = _digits; | 328 var digits = _digits; |
| 325 var r_digits = new Uint32List(r_used + (r_used & 1)); | 329 var r_digits = new Uint32List(r_used + (r_used & 1)); |
| 326 r_digits[0] = digits[ds] >> bs; | 330 r_digits[0] = digits[ds] >> bs; |
| 327 var used = _used; | 331 var used = _used; |
| 328 for (var i = ds + 1; i < used; i++) { | 332 for (var i = ds + 1; i < used; i++) { |
| 329 r_digits[i - ds - 1] |= (digits[i] & bm) << cbs; | 333 final d = digits[i]; |
| 330 r_digits[i - ds] = digits[i] >> bs; | 334 r_digits[i - ds - 1] |= (d & bm) << cbs; |
| 335 r_digits[i - ds] = d >> bs; |
| 331 } | 336 } |
| 332 var r = new _Bigint(_neg, r_used, r_digits); | 337 var r = new _Bigint(_neg, r_used, r_digits); |
| 333 if (_neg) { | 338 if (_neg) { |
| 334 // Round down if any bit was shifted out. | 339 // Round down if any bit was shifted out. |
| 335 if ((digits[ds] & bm) != 0) { | 340 if ((digits[ds] & bm) != 0) { |
| 336 return r._sub(_ONE); | 341 return r._sub(_ONE); |
| 337 } | 342 } |
| 338 for (var i = 0; i < ds; i++) { | 343 for (var i = 0; i < ds; i++) { |
| 339 if (digits[i] != 0) { | 344 if (digits[i] != 0) { |
| 340 return r._sub(_ONE); | 345 return r._sub(_ONE); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 355 } | 360 } |
| 356 var r_used = x_used - ds; | 361 var r_used = x_used - ds; |
| 357 if (r_used <= 0) { | 362 if (r_used <= 0) { |
| 358 return 0; | 363 return 0; |
| 359 } | 364 } |
| 360 var cbs = _DIGIT_BITS - bs; | 365 var cbs = _DIGIT_BITS - bs; |
| 361 var bm = (1 << bs) - 1; | 366 var bm = (1 << bs) - 1; |
| 362 assert(r_digits.length >= r_used + (r_used & 1)); | 367 assert(r_digits.length >= r_used + (r_used & 1)); |
| 363 r_digits[0] = x_digits[ds] >> bs; | 368 r_digits[0] = x_digits[ds] >> bs; |
| 364 for (var i = ds + 1; i < x_used; i++) { | 369 for (var i = ds + 1; i < x_used; i++) { |
| 365 r_digits[i - ds - 1] |= (x_digits[i] & bm) << cbs; | 370 final d = x_digits[i]; |
| 366 r_digits[i - ds] = x_digits[i] >> bs; | 371 r_digits[i - ds - 1] |= (d & bm) << cbs; |
| 372 r_digits[i - ds] = d >> bs; |
| 367 } | 373 } |
| 368 if (r_used.isOdd) { | 374 if (r_digits[r_used - 1] == 0) { |
| 375 r_used--; // Clamp result. |
| 376 } else if (r_used.isOdd) { |
| 369 r_digits[r_used] = 0; | 377 r_digits[r_used] = 0; |
| 370 } | 378 } |
| 371 return r_used; | 379 return r_used; |
| 372 } | 380 } |
| 373 | 381 |
| 374 // Return 0 if abs(this) == abs(a). | 382 // Return 0 if abs(this) == abs(a). |
| 375 // Return a positive number if abs(this) > abs(a). | 383 // Return a positive number if abs(this) > abs(a). |
| 376 // Return a negative number if abs(this) < abs(a). | 384 // Return a negative number if abs(this) < abs(a). |
| 377 int _absCompare(_Bigint a) { | 385 int _absCompare(_Bigint a) { |
| 378 var r = _used - a._used; | 386 var r = _used - a._used; |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 _Bigint _divRem(_Bigint a, bool div) { | 956 _Bigint _divRem(_Bigint a, bool div) { |
| 949 assert(a._used > 0); | 957 assert(a._used > 0); |
| 950 if (_used < a._used) { | 958 if (_used < a._used) { |
| 951 return div ? _ZERO : this; | 959 return div ? _ZERO : this; |
| 952 } | 960 } |
| 953 var nsh = _DIGIT_BITS - _nbits(a._digits[a._used - 1]); | 961 var nsh = _DIGIT_BITS - _nbits(a._digits[a._used - 1]); |
| 954 // For 64-bit processing, make sure y has an even number of digits. | 962 // For 64-bit processing, make sure y has an even number of digits. |
| 955 if (a._used.isOdd) { | 963 if (a._used.isOdd) { |
| 956 nsh += _DIGIT_BITS; | 964 nsh += _DIGIT_BITS; |
| 957 } | 965 } |
| 958 var y; // Normalized positive divisor. | 966 // Concatenated positive quotient and normalized positive remainder. |
| 959 var r; // Concatenated positive quotient and normalized positive remainder. | 967 var r_digits; |
| 968 var r_used; |
| 969 // Normalized positive divisor. |
| 970 var y_digits; |
| 971 var y_used; |
| 960 if (nsh > 0) { | 972 if (nsh > 0) { |
| 961 y = a._lShift(nsh)._abs(); | 973 y_digits = new Uint32List(a._used + 3); // +3 for normalization. |
| 962 r = _lShift(nsh)._abs(); | 974 y_used = _lShiftDigits(a._digits, a._used, nsh, y_digits); |
| 975 r_digits = new Uint32List(_used + 3); // +3 for normalization. |
| 976 r_used = _lShiftDigits(_digits, _used, nsh, r_digits); |
| 977 } else { |
| 978 y_digits = a._digits; |
| 979 y_used = a._used; |
| 980 r_digits = _cloneDigits(_digits, 0, _used, _used + 2); |
| 981 r_used = _used; |
| 963 } | 982 } |
| 964 else { | 983 Uint32List yt_qd = new Uint32List(4); |
| 965 y = a._abs(); | 984 yt_qd[_YT_LO] = y_digits[y_used - 2]; |
| 966 r = _abs(); | 985 yt_qd[_YT] = y_digits[y_used - 1]; |
| 967 } | |
| 968 var y_used = y._used; | |
| 969 var y_digits = y._digits; | |
| 970 Uint32List args = new Uint32List(4); | |
| 971 args[_YT_LO] = y_digits[y_used - 2]; | |
| 972 args[_YT] = y_digits[y_used - 1]; | |
| 973 var r_used = r._used; | |
| 974 // For 64-bit processing, make sure y_used, i, and j are even. | 986 // For 64-bit processing, make sure y_used, i, and j are even. |
| 975 assert(y_used.isEven); | 987 assert(y_used.isEven); |
| 976 var i = r_used + (r_used & 1); | 988 var i = r_used + (r_used & 1); |
| 977 var j = i - y_used; | 989 var j = i - y_used; |
| 978 var t = y._dlShift(j); | 990 // t_digits is a temporary array of i digits. |
| 979 if (r._compare(t) >= 0) { | 991 var t_digits = new Uint32List(i); |
| 992 var t_used = _dlShiftDigits(y_digits, y_used, j, t_digits); |
| 993 // Explicit first division step in case normalized dividend is larger or |
| 994 // equal to shifted normalized divisor. |
| 995 if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) { |
| 980 assert(i == r_used); | 996 assert(i == r_used); |
| 981 r = r._or(_ONE._dlShift(r_used++))._sub(t); | 997 r_digits[r_used++] = 1; // Quotient = 1. |
| 982 assert(r._used == r_used && (i + 1) == r_used); | 998 r_digits[r_used] = 0; // Leading zero. |
| 999 // Subtract divisor from remainder. |
| 1000 _absSub(r_digits, r_used, t_digits, t_used, r_digits); |
| 983 } | 1001 } |
| 984 // Negate y so we can later use _mulAdd instead of non-existent _mulSub. | 1002 // Negate y so we can later use _mulAdd instead of non-existent _mulSub. |
| 985 y = _ONE._dlShift(y_used)._sub(y); | 1003 var ny_digits = new Uint32List(y_used + 2); |
| 986 if (y._used < y_used) { | 1004 ny_digits[y_used] = 1; |
| 987 y_digits = _cloneDigits(y._digits, 0, y._used, y_used); | 1005 _absSub(ny_digits, y_used + 1, y_digits, y_used, ny_digits); |
| 988 } else { | 1006 // ny_digits is read-only and has y_used digits (possibly including several |
| 989 y_digits = y._digits; | |
| 990 } | |
| 991 // y_digits is read-only and has y_used digits (possibly including several | |
| 992 // leading zeros) plus a leading zero for 64-bit processing. | 1007 // leading zeros) plus a leading zero for 64-bit processing. |
| 993 var r_digits = _cloneDigits(r._digits, 0, r._used, i + 1); | |
| 994 // r_digits is modified during iteration. | 1008 // r_digits is modified during iteration. |
| 995 // r_digits[0..y_used-1] is the current remainder. | 1009 // r_digits[0..y_used-1] is the current remainder. |
| 996 // r_digits[y_used..r_used-1] is the current quotient. | 1010 // r_digits[y_used..r_used-1] is the current quotient. |
| 997 --i; | 1011 --i; |
| 998 while (j > 0) { | 1012 while (j > 0) { |
| 999 var d0 = _estQuotientDigit(args, r_digits, i); | 1013 var d0 = _estQuotientDigit(yt_qd, r_digits, i); |
| 1000 j -= d0; | 1014 j -= d0; |
| 1001 var d1 = _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); | 1015 var d1 = _mulAdd(yt_qd, _QD, ny_digits, 0, r_digits, j, y_used); |
| 1002 // _estQuotientDigit and _mulAdd must agree on the number of digits to | 1016 // _estQuotientDigit and _mulAdd must agree on the number of digits to |
| 1003 // process. | 1017 // process. |
| 1004 assert(d0 == d1); | 1018 assert(d0 == d1); |
| 1005 if (d0 == 1) { | 1019 if (d0 == 1) { |
| 1006 if (r_digits[i] < args[_QD]) { | 1020 if (r_digits[i] < yt_qd[_QD]) { |
| 1007 var t = y._dlShift(j); | 1021 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits); |
| 1008 var t_digits = t._digits; | |
| 1009 var t_used = t._used; | |
| 1010 _absSub(r_digits, r_used, t_digits, t_used, r_digits); | 1022 _absSub(r_digits, r_used, t_digits, t_used, r_digits); |
| 1011 while (r_digits[i] < --args[_QD]) { | 1023 while (r_digits[i] < --yt_qd[_QD]) { |
| 1012 _absSub(r_digits, r_used, t_digits, t_used, r_digits); | 1024 _absSub(r_digits, r_used, t_digits, t_used, r_digits); |
| 1013 } | 1025 } |
| 1014 } | 1026 } |
| 1015 } else { | 1027 } else { |
| 1016 assert(d0 == 2); | 1028 assert(d0 == 2); |
| 1017 assert(r_digits[i] <= args[_QD_HI]); | 1029 assert(r_digits[i] <= yt_qd[_QD_HI]); |
| 1018 if ((r_digits[i] < args[_QD_HI]) || (r_digits[i-1] < args[_QD])) { | 1030 if ((r_digits[i] < yt_qd[_QD_HI]) || (r_digits[i-1] < yt_qd[_QD])) { |
| 1019 var t = y._dlShift(j); | 1031 var t_used = _dlShiftDigits(ny_digits, y_used, j, t_digits); |
| 1020 var t_digits = t._digits; | |
| 1021 var t_used = t._used; | |
| 1022 _absSub(r_digits, r_used, t_digits, t_used, r_digits); | 1032 _absSub(r_digits, r_used, t_digits, t_used, r_digits); |
| 1023 if (args[_QD] == 0) { | 1033 if (yt_qd[_QD] == 0) { |
| 1024 --args[_QD_HI]; | 1034 --yt_qd[_QD_HI]; |
| 1025 } | 1035 } |
| 1026 --args[_QD]; | 1036 --yt_qd[_QD]; |
| 1027 assert(r_digits[i] <= args[_QD_HI]); | 1037 assert(r_digits[i] <= yt_qd[_QD_HI]); |
| 1028 while ((r_digits[i] < args[_QD_HI]) || (r_digits[i-1] < args[_QD])) { | 1038 while ((r_digits[i] < yt_qd[_QD_HI]) || |
| 1039 (r_digits[i-1] < yt_qd[_QD])) { |
| 1029 _absSub(r_digits, r_used, t_digits, t_used, r_digits); | 1040 _absSub(r_digits, r_used, t_digits, t_used, r_digits); |
| 1030 if (args[_QD] == 0) { | 1041 if (yt_qd[_QD] == 0) { |
| 1031 --args[_QD_HI]; | 1042 --yt_qd[_QD_HI]; |
| 1032 } | 1043 } |
| 1033 --args[_QD]; | 1044 --yt_qd[_QD]; |
| 1034 assert(r_digits[i] <= args[_QD_HI]); | 1045 assert(r_digits[i] <= yt_qd[_QD_HI]); |
| 1035 } | 1046 } |
| 1036 } | 1047 } |
| 1037 } | 1048 } |
| 1038 i -= d0; | 1049 i -= d0; |
| 1039 } | 1050 } |
| 1040 if (div) { | 1051 if (div) { |
| 1041 // Return quotient, i.e. r_digits[y_used..r_used-1] with proper sign. | 1052 // Return quotient, i.e. r_digits[y_used..r_used-1] with proper sign. |
| 1042 r_digits = _cloneDigits(r_digits, y_used, r_used, r_used - y_used); | 1053 r_digits = _cloneDigits(r_digits, y_used, r_used, r_used - y_used); |
| 1043 r = new _Bigint(false, r_used - y_used, r_digits); | 1054 var r = new _Bigint(false, r_used - y_used, r_digits); |
| 1044 if (_neg != a._neg && r._used > 0) { | 1055 if (_neg != a._neg && r._used > 0) { |
| 1045 r = r._negate(); | 1056 r = r._negate(); |
| 1046 } | 1057 } |
| 1047 return r; | 1058 return r; |
| 1048 } | 1059 } |
| 1049 // Return remainder, i.e. denormalized r_digits[0..y_used-1] with | 1060 // Return remainder, i.e. denormalized r_digits[0..y_used-1] with |
| 1050 // proper sign. | 1061 // proper sign. |
| 1051 r_digits = _cloneDigits(r_digits, 0, y_used, y_used); | 1062 r_digits = _cloneDigits(r_digits, 0, y_used, y_used); |
| 1052 r = new _Bigint(false, y_used, r_digits); | 1063 var r = new _Bigint(false, y_used, r_digits); |
| 1053 if (nsh > 0) { | 1064 if (nsh > 0) { |
| 1054 r = r._rShift(nsh); // Denormalize remainder. | 1065 r = r._rShift(nsh); // Denormalize remainder. |
| 1055 } | 1066 } |
| 1056 if (_neg && r._used > 0) { | 1067 if (_neg && r._used > 0) { |
| 1057 r = r._negate(); | 1068 r = r._negate(); |
| 1058 } | 1069 } |
| 1059 return r; | 1070 return r; |
| 1060 } | 1071 } |
| 1061 | 1072 |
| 1062 // Customized version of _rem() minimizing allocations for use in reduction. | 1073 // Customized version of _rem() minimizing allocations for use in reduction. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 } | 1193 } |
| 1183 | 1194 |
| 1184 // This method must support smi._toBigint()._shlFromInt(int). | 1195 // This method must support smi._toBigint()._shlFromInt(int). |
| 1185 // An out of memory exception is thrown if the result cannot be allocated. | 1196 // An out of memory exception is thrown if the result cannot be allocated. |
| 1186 int _shlFromInt(int other) { | 1197 int _shlFromInt(int other) { |
| 1187 if (_used == 0) return other; // Shift amount is zero. | 1198 if (_used == 0) return other; // Shift amount is zero. |
| 1188 if (_neg) throw new RangeError(this); | 1199 if (_neg) throw new RangeError(this); |
| 1189 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. | 1200 assert(_DIGIT_BITS == 32); // Otherwise this code needs to be revised. |
| 1190 var shift; | 1201 var shift; |
| 1191 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) { | 1202 if (_used > 2 || (_used == 2 && _digits[1] > 0x10000000)) { |
| 1203 if (other == 0) return 0; // Shifted value is zero. |
| 1192 throw new OutOfMemoryError(); | 1204 throw new OutOfMemoryError(); |
| 1193 } else { | 1205 } else { |
| 1194 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; | 1206 shift = ((_used == 2) ? (_digits[1] << _DIGIT_BITS) : 0) + _digits[0]; |
| 1195 } | 1207 } |
| 1196 return other._toBigint()._lShift(shift)._toValidInt(); | 1208 return other._toBigint()._lShift(shift)._toValidInt(); |
| 1197 } | 1209 } |
| 1198 | 1210 |
| 1199 // Overriden operators and methods. | 1211 // Overriden operators and methods. |
| 1200 | 1212 |
| 1201 // The following operators override operators of _IntegerImplementation for | 1213 // The following operators override operators of _IntegerImplementation for |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1691 var neg_norm_m = _Bigint._ONE._dlShift(nm_used)._sub(_norm_m); | 1703 var neg_norm_m = _Bigint._ONE._dlShift(nm_used)._sub(_norm_m); |
| 1692 if (neg_norm_m._used < nm_used) { | 1704 if (neg_norm_m._used < nm_used) { |
| 1693 _neg_norm_m_digits = | 1705 _neg_norm_m_digits = |
| 1694 _Bigint._cloneDigits(neg_norm_m._digits, 0, nm_used, nm_used); | 1706 _Bigint._cloneDigits(neg_norm_m._digits, 0, nm_used, nm_used); |
| 1695 } else { | 1707 } else { |
| 1696 _neg_norm_m_digits = neg_norm_m._digits; | 1708 _neg_norm_m_digits = neg_norm_m._digits; |
| 1697 } | 1709 } |
| 1698 // _neg_norm_m_digits is read-only and has nm_used digits (possibly | 1710 // _neg_norm_m_digits is read-only and has nm_used digits (possibly |
| 1699 // including several leading zeros) plus a leading zero for 64-bit | 1711 // including several leading zeros) plus a leading zero for 64-bit |
| 1700 // processing. | 1712 // processing. |
| 1701 _t_digits = new Uint32List(2*nm_used + 2); | 1713 _t_digits = new Uint32List(2*nm_used); |
| 1702 } | 1714 } |
| 1703 | 1715 |
| 1704 int _convert(_Bigint x, Uint32List r_digits) { | 1716 int _convert(_Bigint x, Uint32List r_digits) { |
| 1705 var digits; | 1717 var digits; |
| 1706 var used; | 1718 var used; |
| 1707 if (x._neg || x._compare(_m) >= 0) { | 1719 if (x._neg || x._compare(_m) >= 0) { |
| 1708 var r = x._rem(_m); | 1720 var r = x._rem(_m); |
| 1709 if (x._neg && !r._neg && r._used > 0) { | 1721 if (x._neg && !r._neg && r._used > 0) { |
| 1710 r = _m._sub(r); | 1722 r = _m._sub(r); |
| 1711 } | 1723 } |
| 1712 assert(!r._neg); | 1724 assert(!r._neg); |
| 1713 used = r._used; | 1725 used = r._used; |
| 1714 digits = r._digits; | 1726 digits = r._digits; |
| 1715 } else { | 1727 } else { |
| 1716 used = x._used; | 1728 used = x._used; |
| 1717 digits = x._digits; | 1729 digits = x._digits; |
| 1718 } | 1730 } |
| 1719 var i = used + (used & 1); // Copy leading zero if any. | 1731 var i = used + (used & 1); // Copy leading zero if any. |
| 1720 while (--i >= 0) { | 1732 while (--i >= 0) { |
| 1721 r_digits[i] = digits[i]; | 1733 r_digits[i] = digits[i]; |
| 1722 } | 1734 } |
| 1723 return used; | 1735 return used; |
| 1724 } | 1736 } |
| 1725 | 1737 |
| 1726 _Bigint _revert(Uint32List x_digits, int x_used) { | 1738 _Bigint _revert(Uint32List x_digits, int x_used) { |
| 1727 return new _Bigint(false, x_used, x_digits); | 1739 return new _Bigint(false, x_used, x_digits); |
| 1728 } | 1740 } |
| 1729 | 1741 |
| 1730 int _reduce(Uint32List x_digits, int x_used) { | 1742 int _reduce(Uint32List x_digits, int x_used) { |
| 1743 if (x_used < _m._used) { |
| 1744 return x_used; |
| 1745 } |
| 1731 // The function _remDigits(...) is optimized for reduction and equivalent to | 1746 // The function _remDigits(...) is optimized for reduction and equivalent to |
| 1732 // calling _convert(_revert(x_digits, x_used)._rem(_m), x_digits); | 1747 // calling _convert(_revert(x_digits, x_used)._rem(_m), x_digits); |
| 1733 return _Bigint._remDigits(x_digits, x_used, | 1748 return _Bigint._remDigits(x_digits, x_used, |
| 1734 _norm_m._digits, _norm_m._used, | 1749 _norm_m._digits, _norm_m._used, |
| 1735 _neg_norm_m_digits, | 1750 _neg_norm_m_digits, |
| 1736 _m_nsh, | 1751 _m_nsh, |
| 1737 _mt_qd, | 1752 _mt_qd, |
| 1738 _t_digits, | 1753 _t_digits, |
| 1739 x_digits); | 1754 x_digits); |
| 1740 } | 1755 } |
| 1741 | 1756 |
| 1742 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits) { | 1757 int _sqr(Uint32List x_digits, int x_used, Uint32List r_digits) { |
| 1743 var r_used = _Bigint._sqrDigits(x_digits, x_used, r_digits); | 1758 var r_used = _Bigint._sqrDigits(x_digits, x_used, r_digits); |
| 1744 return _reduce(r_digits, r_used); | 1759 return _reduce(r_digits, r_used); |
| 1745 } | 1760 } |
| 1746 | 1761 |
| 1747 int _mul(Uint32List x_digits, int x_used, | 1762 int _mul(Uint32List x_digits, int x_used, |
| 1748 Uint32List y_digits, int y_used, | 1763 Uint32List y_digits, int y_used, |
| 1749 Uint32List r_digits) { | 1764 Uint32List r_digits) { |
| 1750 var r_used = _Bigint._mulDigits(x_digits, x_used, | 1765 var r_used = _Bigint._mulDigits(x_digits, x_used, |
| 1751 y_digits, y_used, | 1766 y_digits, y_used, |
| 1752 r_digits); | 1767 r_digits); |
| 1753 return _reduce(r_digits, r_used); | 1768 return _reduce(r_digits, r_used); |
| 1754 } | 1769 } |
| 1755 } | 1770 } |
| OLD | NEW |