| 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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 return -((digits[1] << DIGIT_BITS) | digits[0]); | 196 return -((digits[1] << DIGIT_BITS) | digits[0]); |
| 197 } | 197 } |
| 198 if (digits[1] >= 0x80000000) return this; | 198 if (digits[1] >= 0x80000000) return this; |
| 199 return (digits[1] << DIGIT_BITS) | digits[0]; | 199 return (digits[1] << DIGIT_BITS) | digits[0]; |
| 200 } | 200 } |
| 201 | 201 |
| 202 // Conversion from int to bigint. | 202 // Conversion from int to bigint. |
| 203 _Bigint _toBigint() => this; | 203 _Bigint _toBigint() => this; |
| 204 | 204 |
| 205 // Make sure at least 'length' _digits are allocated. | 205 // Make sure at least 'length' _digits are allocated. |
| 206 // Copy existing _digits if reallocation is necessary. | 206 // Copy existing and used _digits if reallocation is necessary. |
| 207 // TODO(regis): Check that we are not preserving _digits unnecessarily. | 207 // Avoid preserving _digits unnecessarily by calling this function with a |
| 208 // meaningful _used field. |
| 208 void _ensureLength(int length) { | 209 void _ensureLength(int length) { |
| 209 var digits = _digits; | 210 var digits = _digits; |
| 210 if (length > 0 && (length > digits.length)) { | 211 if (length > digits.length) { |
| 211 var new_digits = new Uint32List(length + EXTRA_DIGITS); | 212 var new_digits = new Uint32List(length + EXTRA_DIGITS); |
| 212 for (var i = _used; --i >= 0; ) { | 213 _digits = new_digits; |
| 213 new_digits[i] = digits[i]; | 214 if (_used > 0) { |
| 215 var i = _used + 1; // Copy leading zero for 64-bit processing. |
| 216 while (--i >= 0) { |
| 217 new_digits[i] = digits[i]; |
| 218 } |
| 214 } | 219 } |
| 215 _digits = new_digits; | |
| 216 } | 220 } |
| 217 } | 221 } |
| 218 | 222 |
| 219 // Clamp off excess high _digits. | 223 // Clamp off excess high _digits. |
| 220 void _clamp() { | 224 void _clamp() { |
| 221 var digits = _digits; | 225 var used = _used; |
| 222 while (_used > 0 && digits[_used - 1] == 0) { | 226 if (used > 0) { |
| 223 --_used; | 227 var digits = _digits; |
| 228 if (digits[used - 1] == 0) { |
| 229 do { |
| 230 --used; |
| 231 } while (used > 0 && digits[used - 1] == 0); |
| 232 _used = used; |
| 233 } |
| 234 digits[used] = 0; // Set leading zero for 64-bit processing. |
| 224 } | 235 } |
| 225 } | 236 } |
| 226 | 237 |
| 227 // Copy this to r. | 238 // Copy this to r. |
| 228 void _copyTo(_Bigint r) { | 239 void _copyTo(_Bigint r) { |
| 229 r._ensureLength(_used); | 240 var used = _used; |
| 230 var digits = _digits; | 241 if (used > 0) { |
| 231 var r_digits = r._digits; | 242 r._used = 0; // No digits to preserve. |
| 232 for (var i = _used - 1; i >= 0; --i) { | 243 r._ensureLength(used); |
| 233 r_digits[i] = digits[i]; | 244 var digits = _digits; |
| 245 var r_digits = r._digits; |
| 246 var i = used + 1; // Copy leading zero for 64-bit processing. |
| 247 while (--i >= 0) { |
| 248 r_digits[i] = digits[i]; |
| 249 } |
| 234 } | 250 } |
| 235 r._used = _used; | 251 r._used = used; |
| 236 r._neg = _neg; | 252 r._neg = _neg; |
| 237 } | 253 } |
| 238 | 254 |
| 239 // Return the bit length of digit x. | 255 // Return the bit length of digit x. |
| 240 int _nbits(int x) { | 256 int _nbits(int x) { |
| 241 var r = 1, t; | 257 var r = 1, t; |
| 242 if ((t = x >> 16) != 0) { x = t; r += 16; } | 258 if ((t = x >> 16) != 0) { x = t; r += 16; } |
| 243 if ((t = x >> 8) != 0) { x = t; r += 8; } | 259 if ((t = x >> 8) != 0) { x = t; r += 8; } |
| 244 if ((t = x >> 4) != 0) { x = t; r += 4; } | 260 if ((t = x >> 4) != 0) { x = t; r += 4; } |
| 245 if ((t = x >> 2) != 0) { x = t; r += 2; } | 261 if ((t = x >> 2) != 0) { x = t; r += 2; } |
| 246 if ((x >> 1) != 0) { r += 1; } | 262 if ((x >> 1) != 0) { r += 1; } |
| 247 return r; | 263 return r; |
| 248 } | 264 } |
| 249 | 265 |
| 250 // r = this << n*DIGIT_BITS. | 266 // r = this << n*DIGIT_BITS. |
| 251 void _dlShiftTo(int n, _Bigint r) { | 267 void _dlShiftTo(int n, _Bigint r) { |
| 252 var r_used = _used + n; | 268 var used = _used; |
| 269 if (used == 0) { |
| 270 r._used = 0; |
| 271 r._neg = false; |
| 272 return; |
| 273 } |
| 274 var r_used = used + n; |
| 253 r._ensureLength(r_used); | 275 r._ensureLength(r_used); |
| 254 var digits = _digits; | 276 var digits = _digits; |
| 255 var r_digits = r._digits; | 277 var r_digits = r._digits; |
| 256 for (var i = _used - 1; i >= 0; --i) { | 278 var i = used + 1; // Copy leading zero for 64-bit processing. |
| 279 while (--i >= 0) { |
| 257 r_digits[i + n] = digits[i]; | 280 r_digits[i + n] = digits[i]; |
| 258 } | 281 } |
| 259 for (var i = n - 1; i >= 0; --i) { | 282 i = n; |
| 283 while (--i >= 0) { |
| 260 r_digits[i] = 0; | 284 r_digits[i] = 0; |
| 261 } | 285 } |
| 262 r._used = r_used; | 286 r._used = r_used; |
| 263 r._neg = _neg; | 287 r._neg = _neg; |
| 264 } | 288 } |
| 265 | 289 |
| 266 // r = this >> n*DIGIT_BITS. | 290 // r = this >> n*DIGIT_BITS. |
| 267 void _drShiftTo(int n, _Bigint r) { | 291 void _drShiftTo(int n, _Bigint r) { |
| 268 var r_used = _used - n; | 292 var used = _used; |
| 269 if (r_used < 0) { | 293 if (used == 0) { |
| 294 r._used = 0; |
| 295 r._neg = false; |
| 296 return; |
| 297 } |
| 298 var r_used = used - n; |
| 299 if (r_used <= 0) { |
| 270 if (_neg) { | 300 if (_neg) { |
| 271 // Set r to -1. | 301 // Set r to -1. |
| 302 r._used = 0; // No digits to preserve. |
| 303 r._ensureLength(1); |
| 272 r._neg = true; | 304 r._neg = true; |
| 273 r._ensureLength(1); | |
| 274 r._used = 1; | 305 r._used = 1; |
| 275 r._digits[0] = 1; | 306 r._digits[0] = 1; |
| 307 r._digits[1] = 0; // Set leading zero for 64-bit processing. |
| 276 } else { | 308 } else { |
| 277 // Set r to 0. | 309 // Set r to 0. |
| 278 r._neg = false; | 310 r._neg = false; |
| 279 r._used = 0; | 311 r._used = 0; |
| 280 } | 312 } |
| 281 return; | 313 return; |
| 282 } | 314 } |
| 283 r._ensureLength(r_used); | 315 r._ensureLength(r_used); |
| 284 var digits = _digits; | 316 var digits = _digits; |
| 285 var r_digits = r._digits; | 317 var r_digits = r._digits; |
| 286 var used = _used; | 318 for (var i = n; i < used + 1; i++) { // Copy leading zero for 64-bit proc. |
| 287 for (var i = n; i < used; ++i) { | |
| 288 r_digits[i - n] = digits[i]; | 319 r_digits[i - n] = digits[i]; |
| 289 } | 320 } |
| 290 r._used = r_used; | 321 r._used = r_used; |
| 291 r._neg = _neg; | 322 r._neg = _neg; |
| 292 if (_neg) { | 323 if (_neg) { |
| 293 // Round down if any bit was shifted out. | 324 // Round down if any bit was shifted out. |
| 294 for (var i = 0; i < n; i++) { | 325 for (var i = 0; i < n; i++) { |
| 295 if (digits[i] != 0) { | 326 if (digits[i] != 0) { |
| 296 r._subTo(ONE, r); | 327 r._subTo(ONE, r); |
| 297 break; | 328 break; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 308 _dlShiftTo(ds, r); | 339 _dlShiftTo(ds, r); |
| 309 return; | 340 return; |
| 310 } | 341 } |
| 311 var cbs = DIGIT_BITS - bs; | 342 var cbs = DIGIT_BITS - bs; |
| 312 var bm = (1 << cbs) - 1; | 343 var bm = (1 << cbs) - 1; |
| 313 var r_used = _used + ds + 1; | 344 var r_used = _used + ds + 1; |
| 314 r._ensureLength(r_used); | 345 r._ensureLength(r_used); |
| 315 var digits = _digits; | 346 var digits = _digits; |
| 316 var r_digits = r._digits; | 347 var r_digits = r._digits; |
| 317 var c = 0; | 348 var c = 0; |
| 318 for (var i = _used - 1; i >= 0; --i) { | 349 var i = _used; |
| 350 while (--i >= 0) { |
| 319 r_digits[i + ds + 1] = (digits[i] >> cbs) | c; | 351 r_digits[i + ds + 1] = (digits[i] >> cbs) | c; |
| 320 c = (digits[i] & bm) << bs; | 352 c = (digits[i] & bm) << bs; |
| 321 } | 353 } |
| 322 for (var i = ds - 1; i >= 0; --i) { | 354 i = ds; |
| 355 while (--i >= 0) { |
| 323 r_digits[i] = 0; | 356 r_digits[i] = 0; |
| 324 } | 357 } |
| 325 r_digits[ds] = c; | 358 r_digits[ds] = c; |
| 326 r._used = r_used; | 359 r._used = r_used; |
| 327 r._neg = _neg; | 360 r._neg = _neg; |
| 328 r._clamp(); | 361 r._clamp(); |
| 329 } | 362 } |
| 330 | 363 |
| 331 // r = this >> n. | 364 // r = this >> n. |
| 332 void _rShiftTo(int n, _Bigint r) { | 365 void _rShiftTo(int n, _Bigint r) { |
| 333 var ds = n ~/ DIGIT_BITS; | 366 var ds = n ~/ DIGIT_BITS; |
| 334 var bs = n % DIGIT_BITS; | 367 var bs = n % DIGIT_BITS; |
| 335 if (bs == 0) { | 368 if (bs == 0) { |
| 336 _drShiftTo(ds, r); | 369 _drShiftTo(ds, r); |
| 337 return; | 370 return; |
| 338 } | 371 } |
| 339 var r_used = _used - ds; | 372 var r_used = _used - ds; |
| 340 if (r_used <= 0) { | 373 if (r_used <= 0) { |
| 341 if (_neg) { | 374 if (_neg) { |
| 342 // Set r to -1. | 375 // Set r to -1. |
| 343 r._neg = true; | 376 r._neg = true; |
| 377 r._used = 0; // No digits to preserve. |
| 344 r._ensureLength(1); | 378 r._ensureLength(1); |
| 345 r._used = 1; | 379 r._used = 1; |
| 346 r._digits[0] = 1; | 380 r._digits[0] = 1; |
| 381 r._digits[1] = 0; // Set leading zero for 64-bit processing. |
| 347 } else { | 382 } else { |
| 348 // Set r to 0. | 383 // Set r to 0. |
| 349 r._neg = false; | 384 r._neg = false; |
| 350 r._used = 0; | 385 r._used = 0; |
| 351 } | 386 } |
| 352 return; | 387 return; |
| 353 } | 388 } |
| 354 var cbs = DIGIT_BITS - bs; | 389 var cbs = DIGIT_BITS - bs; |
| 355 var bm = (1 << bs) - 1; | 390 var bm = (1 << bs) - 1; |
| 356 r._ensureLength(r_used); | 391 r._ensureLength(r_used); |
| 357 var digits = _digits; | 392 var digits = _digits; |
| 358 var r_digits = r._digits; | 393 var r_digits = r._digits; |
| 359 r_digits[0] = digits[ds] >> bs; | 394 r_digits[0] = digits[ds] >> bs; |
| 360 var used = _used; | 395 var used = _used; |
| 361 for (var i = ds + 1; i < used; ++i) { | 396 for (var i = ds + 1; i < used; i++) { |
| 362 r_digits[i - ds - 1] |= (digits[i] & bm) << cbs; | 397 r_digits[i - ds - 1] |= (digits[i] & bm) << cbs; |
| 363 r_digits[i - ds] = digits[i] >> bs; | 398 r_digits[i - ds] = digits[i] >> bs; |
| 364 } | 399 } |
| 365 r._neg = _neg; | 400 r._neg = _neg; |
| 366 r._used = r_used; | 401 r._used = r_used; |
| 367 r._clamp(); | 402 r._clamp(); |
| 368 if (_neg) { | 403 if (_neg) { |
| 369 // Round down if any bit was shifted out. | 404 // Round down if any bit was shifted out. |
| 370 if ((digits[ds] & bm) != 0) { | 405 if ((digits[ds] & bm) != 0) { |
| 371 r._subTo(ONE, r); | 406 r._subTo(ONE, r); |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 } else { | 895 } else { |
| 861 a_digits[i + used] = c; | 896 a_digits[i + used] = c; |
| 862 } | 897 } |
| 863 } | 898 } |
| 864 | 899 |
| 865 // r = this * a. | 900 // r = this * a. |
| 866 void _mulTo(_Bigint a, _Bigint r) { | 901 void _mulTo(_Bigint a, _Bigint r) { |
| 867 // TODO(regis): Use karatsuba multiplication when appropriate. | 902 // TODO(regis): Use karatsuba multiplication when appropriate. |
| 868 var used = _used; | 903 var used = _used; |
| 869 var a_used = a._used; | 904 var a_used = a._used; |
| 905 if (used == 0 || a_used == 0) { |
| 906 r._used = 0; |
| 907 r._neg = false; |
| 908 return; |
| 909 } |
| 870 var r_used = used + a_used; | 910 var r_used = used + a_used; |
| 871 r._ensureLength(r_used); | 911 r._ensureLength(r_used); |
| 872 var digits = _digits; | 912 var digits = _digits; |
| 873 var a_digits = a._digits; | 913 var a_digits = a._digits; |
| 874 var r_digits = r._digits; | 914 var r_digits = r._digits; |
| 875 r._used = r_used; | 915 r._used = r_used; |
| 876 var i = r_used; | 916 var i = r_used + 1; // Set leading zero for 64-bit processing. |
| 877 while (--i >= 0) { | 917 while (--i >= 0) { |
| 878 r_digits[i] = 0; | 918 r_digits[i] = 0; |
| 879 } | 919 } |
| 880 for (i = 0; i < a_used; ++i) { | 920 for (i = 0; i < a_used; ++i) { |
| 881 _mulAdd(a_digits, i, digits, 0, r_digits, i, used); | 921 _mulAdd(a_digits, i, digits, 0, r_digits, i, used); |
| 882 } | 922 } |
| 883 r._clamp(); | 923 r._clamp(); |
| 884 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. | 924 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. |
| 885 } | 925 } |
| 886 | 926 |
| 887 // r = this^2, r != this. | 927 // r = this^2, r != this. |
| 888 void _sqrTo(_Bigint r) { | 928 void _sqrTo(_Bigint r) { |
| 889 var used = _used; | 929 var used = _used; |
| 930 if (used == 0) { |
| 931 r._used = 0; |
| 932 r._neg = false; |
| 933 return; |
| 934 } |
| 890 var r_used = 2 * used; | 935 var r_used = 2 * used; |
| 891 r._ensureLength(r_used); | 936 r._ensureLength(r_used); |
| 892 var digits = _digits; | 937 var digits = _digits; |
| 893 var r_digits = r._digits; | 938 var r_digits = r._digits; |
| 894 var i = r_used; | 939 var i = r_used + 1; // Set leading zero for 64-bit processing. |
| 895 while (--i >= 0) { | 940 while (--i >= 0) { |
| 896 r_digits[i] = 0; | 941 r_digits[i] = 0; |
| 897 } | 942 } |
| 898 for (i = 0; i < used - 1; ++i) { | 943 for (i = 0; i < used - 1; ++i) { |
| 899 _sqrAdd(digits, i, r_digits, used); | 944 _sqrAdd(digits, i, r_digits, used); |
| 900 } | 945 } |
| 901 if (r_used > 0) { | 946 if (r_used > 0) { |
| 902 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1); | 947 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1); |
| 903 } | 948 } |
| 904 r._used = r_used; | 949 r._used = r_used; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 var y_digits = y._digits; | 1008 var y_digits = y._digits; |
| 964 var yt = y_digits[y_used - 1]; | 1009 var yt = y_digits[y_used - 1]; |
| 965 if (yt == 0) return; | 1010 if (yt == 0) return; |
| 966 var i = r._used; | 1011 var i = r._used; |
| 967 var j = i - y_used; | 1012 var j = i - y_used; |
| 968 _Bigint t = (q == null) ? new _Bigint() : q; | 1013 _Bigint t = (q == null) ? new _Bigint() : q; |
| 969 y._dlShiftTo(j, t); | 1014 y._dlShiftTo(j, t); |
| 970 var r_digits = r._digits; | 1015 var r_digits = r._digits; |
| 971 if (r._compareTo(t) >= 0) { | 1016 if (r._compareTo(t) >= 0) { |
| 972 r_digits[r._used++] = 1; | 1017 r_digits[r._used++] = 1; |
| 1018 r_digits[r._used] = 0; // Set leading zero for 64-bit processing. |
| 973 r._subTo(t, r); | 1019 r._subTo(t, r); |
| 974 } | 1020 } |
| 975 ONE._dlShiftTo(y_used, t); | 1021 ONE._dlShiftTo(y_used, t); |
| 976 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later. | 1022 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later. |
| 977 while (y._used < y_used) { | 1023 while (y._used < y_used) { |
| 978 y_digits[y._used++] = 0; | 1024 y_digits[y._used++] = 0; |
| 979 } | 1025 } |
| 1026 y_digits[y._used] = 0; // Set leading zero for 64-bit processing. |
| 980 Uint32List args = new Uint32List(2); | 1027 Uint32List args = new Uint32List(2); |
| 981 args[_YT] = yt; | 1028 args[_YT] = yt; |
| 982 while (--j >= 0) { | 1029 while (--j >= 0) { |
| 983 _estQuotientDigit(args, r_digits, --i); | 1030 _estQuotientDigit(args, r_digits, --i); |
| 984 _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); | 1031 _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); |
| 985 if (r_digits[i] < args[_QD]) { | 1032 if (r_digits[i] < args[_QD]) { |
| 986 y._dlShiftTo(j, t); | 1033 y._dlShiftTo(j, t); |
| 987 r._subTo(t, r); | 1034 r._subTo(t, r); |
| 988 while (r_digits[i] < --args[_QD]) { | 1035 while (r_digits[i] < --args[_QD]) { |
| 989 r._subTo(t, r); | 1036 r._subTo(t, r); |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1412 return r; | 1459 return r; |
| 1413 } | 1460 } |
| 1414 | 1461 |
| 1415 // x = x/R mod _m | 1462 // x = x/R mod _m |
| 1416 void _reduce(_Bigint x) { | 1463 void _reduce(_Bigint x) { |
| 1417 x._ensureLength(_mused2 + 1); | 1464 x._ensureLength(_mused2 + 1); |
| 1418 var x_digits = x._digits; | 1465 var x_digits = x._digits; |
| 1419 while (x._used <= _mused2) { // Pad x so _mulAdd has enough room later. | 1466 while (x._used <= _mused2) { // Pad x so _mulAdd has enough room later. |
| 1420 x_digits[x._used++] = 0; | 1467 x_digits[x._used++] = 0; |
| 1421 } | 1468 } |
| 1469 x_digits[x._used] = 0; // Set leading zero for 64-bit processing. |
| 1422 var m_used = _m._used; | 1470 var m_used = _m._used; |
| 1423 var m_digits = _m._digits; | 1471 var m_digits = _m._digits; |
| 1424 for (var i = 0; i < m_used; ++i) { | 1472 for (var i = 0; i < m_used; i++) { |
| 1425 _mulMod(_rho_mu, x_digits, i); | 1473 _mulMod(_rho_mu, x_digits, i); |
| 1426 _Bigint._mulAdd(_rho_mu, _MU, m_digits, 0, x_digits, i, m_used); | 1474 _Bigint._mulAdd(_rho_mu, _MU, m_digits, 0, x_digits, i, m_used); |
| 1427 } | 1475 } |
| 1428 x._clamp(); | 1476 x._clamp(); |
| 1429 x._drShiftTo(m_used, x); | 1477 x._drShiftTo(m_used, x); |
| 1430 if (x._compareTo(_m) >= 0) { | 1478 if (x._compareTo(_m) >= 0) { |
| 1431 x._subTo(_m, x); | 1479 x._subTo(_m, x); |
| 1432 } | 1480 } |
| 1433 } | 1481 } |
| 1434 | 1482 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 void _sqrTo(_Bigint x, _Bigint r) { | 1524 void _sqrTo(_Bigint x, _Bigint r) { |
| 1477 x._sqrTo(r); | 1525 x._sqrTo(r); |
| 1478 _reduce(r); | 1526 _reduce(r); |
| 1479 } | 1527 } |
| 1480 | 1528 |
| 1481 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { | 1529 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { |
| 1482 x._mulTo(y, r); | 1530 x._mulTo(y, r); |
| 1483 _reduce(r); | 1531 _reduce(r); |
| 1484 } | 1532 } |
| 1485 } | 1533 } |
| OLD | NEW |