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