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 ZERO = new _Bigint(); | |
| 62 static _Bigint ONE = new _Bigint()._setInt(1); | 61 static _Bigint ONE = new _Bigint()._setInt(1); |
| 63 | 62 |
| 64 // Digit conversion table for parsing. | 63 // Digit conversion table for parsing. |
| 65 static final Map<int, int> DIGIT_TABLE = _createDigitTable(); | 64 static final Map<int, int> DIGIT_TABLE = _createDigitTable(); |
| 66 | 65 |
| 67 // Internal data structure. | 66 // Internal data structure. |
| 68 bool get _neg native "Bigint_getNeg"; | 67 bool get _neg native "Bigint_getNeg"; |
| 69 void set _neg(bool value) native "Bigint_setNeg"; | 68 void set _neg(bool value) native "Bigint_setNeg"; |
| 70 int get _used native "Bigint_getUsed"; | 69 int get _used native "Bigint_getUsed"; |
| 71 void set _used(int value) native "Bigint_setUsed"; | 70 void set _used(int value) native "Bigint_setUsed"; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 return -((digits[1] << DIGIT_BITS) | digits[0]); | 195 return -((digits[1] << DIGIT_BITS) | digits[0]); |
| 197 } | 196 } |
| 198 if (digits[1] >= 0x80000000) return this; | 197 if (digits[1] >= 0x80000000) return this; |
| 199 return (digits[1] << DIGIT_BITS) | digits[0]; | 198 return (digits[1] << DIGIT_BITS) | digits[0]; |
| 200 } | 199 } |
| 201 | 200 |
| 202 // Conversion from int to bigint. | 201 // Conversion from int to bigint. |
| 203 _Bigint _toBigint() => this; | 202 _Bigint _toBigint() => this; |
| 204 | 203 |
| 205 // Make sure at least 'length' _digits are allocated. | 204 // Make sure at least 'length' _digits are allocated. |
| 206 // Copy existing _digits if reallocation is necessary. | 205 // Copy existing and used _digits if reallocation is necessary. |
| 207 // TODO(regis): Check that we are not preserving _digits unnecessarily. | 206 // Avoid preserving _digits unnecessarily by calling this function with a |
| 207 // meaningful _used field. | |
| 208 void _ensureLength(int length) { | 208 void _ensureLength(int length) { |
| 209 length++; // Account for leading zero for 64-bit processing. | |
|
regis
2014/11/20 22:37:23
This increment was dropped by mistake in patch #4
| |
| 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 var used = _used; |
| 215 if (used > 0) { | |
| 216 var i = used + 1; // Copy leading zero for 64-bit processing. | |
| 217 while (--i >= 0) { | |
| 218 new_digits[i] = digits[i]; | |
| 219 } | |
| 214 } | 220 } |
| 215 _digits = new_digits; | |
| 216 } | 221 } |
| 217 } | 222 } |
| 218 | 223 |
| 219 // Clamp off excess high _digits. | 224 // Clamp off excess high _digits. |
| 220 void _clamp() { | 225 void _clamp() { |
| 221 var digits = _digits; | 226 var used = _used; |
| 222 while (_used > 0 && digits[_used - 1] == 0) { | 227 if (used > 0) { |
| 223 --_used; | 228 var digits = _digits; |
| 229 if (digits[used - 1] == 0) { | |
| 230 do { | |
| 231 --used; | |
| 232 } while (used > 0 && digits[used - 1] == 0); | |
| 233 _used = used; | |
| 234 } | |
| 235 digits[used] = 0; // Set leading zero for 64-bit processing. | |
| 224 } | 236 } |
| 225 } | 237 } |
| 226 | 238 |
| 227 // Copy this to r. | 239 // Copy this to r. |
| 228 void _copyTo(_Bigint r) { | 240 void _copyTo(_Bigint r) { |
| 229 r._ensureLength(_used); | 241 var used = _used; |
| 230 var digits = _digits; | 242 if (used > 0) { |
| 231 var r_digits = r._digits; | 243 // We could set r._used to 0 in order to avoid preserving digits. However, |
| 232 for (var i = _used - 1; i >= 0; --i) { | 244 // it would be wrong to do so if this === r. Checking is too expensive. |
| 233 r_digits[i] = digits[i]; | 245 // This case does not occur in the current implementation, but we want to |
| 246 // remain safe. | |
| 247 r._ensureLength(used); | |
| 248 var digits = _digits; | |
| 249 var r_digits = r._digits; | |
| 250 var i = used + 1; // Copy leading zero for 64-bit processing. | |
| 251 while (--i >= 0) { | |
| 252 r_digits[i] = digits[i]; | |
| 253 } | |
| 234 } | 254 } |
| 235 r._used = _used; | 255 r._used = used; |
| 236 r._neg = _neg; | 256 r._neg = _neg; |
| 237 } | 257 } |
| 238 | 258 |
| 239 // Return the bit length of digit x. | 259 // Return the bit length of digit x. |
| 240 int _nbits(int x) { | 260 int _nbits(int x) { |
| 241 var r = 1, t; | 261 var r = 1, t; |
| 242 if ((t = x >> 16) != 0) { x = t; r += 16; } | 262 if ((t = x >> 16) != 0) { x = t; r += 16; } |
| 243 if ((t = x >> 8) != 0) { x = t; r += 8; } | 263 if ((t = x >> 8) != 0) { x = t; r += 8; } |
| 244 if ((t = x >> 4) != 0) { x = t; r += 4; } | 264 if ((t = x >> 4) != 0) { x = t; r += 4; } |
| 245 if ((t = x >> 2) != 0) { x = t; r += 2; } | 265 if ((t = x >> 2) != 0) { x = t; r += 2; } |
| 246 if ((x >> 1) != 0) { r += 1; } | 266 if ((x >> 1) != 0) { r += 1; } |
| 247 return r; | 267 return r; |
| 248 } | 268 } |
| 249 | 269 |
| 250 // r = this << n*DIGIT_BITS. | 270 // r = this << n*DIGIT_BITS. |
| 251 void _dlShiftTo(int n, _Bigint r) { | 271 void _dlShiftTo(int n, _Bigint r) { |
| 252 var r_used = _used + n; | 272 var used = _used; |
| 273 if (used == 0) { | |
| 274 r._used = 0; | |
| 275 r._neg = false; | |
| 276 return; | |
| 277 } | |
| 278 var r_used = used + n; | |
| 253 r._ensureLength(r_used); | 279 r._ensureLength(r_used); |
| 254 var digits = _digits; | 280 var digits = _digits; |
| 255 var r_digits = r._digits; | 281 var r_digits = r._digits; |
| 256 for (var i = _used - 1; i >= 0; --i) { | 282 var i = used + 1; // Copy leading zero for 64-bit processing. |
| 283 while (--i >= 0) { | |
| 257 r_digits[i + n] = digits[i]; | 284 r_digits[i + n] = digits[i]; |
| 258 } | 285 } |
| 259 for (var i = n - 1; i >= 0; --i) { | 286 i = n; |
| 287 while (--i >= 0) { | |
| 260 r_digits[i] = 0; | 288 r_digits[i] = 0; |
| 261 } | 289 } |
| 262 r._used = r_used; | 290 r._used = r_used; |
| 263 r._neg = _neg; | 291 r._neg = _neg; |
| 264 } | 292 } |
| 265 | 293 |
| 266 // r = this >> n*DIGIT_BITS. | 294 // r = this >> n*DIGIT_BITS. |
| 267 void _drShiftTo(int n, _Bigint r) { | 295 void _drShiftTo(int n, _Bigint r) { |
| 268 var r_used = _used - n; | 296 var used = _used; |
| 269 if (r_used < 0) { | 297 if (used == 0) { |
| 298 r._used = 0; | |
| 299 r._neg = false; | |
| 300 return; | |
| 301 } | |
| 302 var r_used = used - n; | |
| 303 if (r_used <= 0) { | |
| 270 if (_neg) { | 304 if (_neg) { |
| 271 // Set r to -1. | 305 // Set r to -1. |
| 306 r._used = 0; // No digits to preserve. | |
| 307 r._ensureLength(1); | |
| 272 r._neg = true; | 308 r._neg = true; |
| 273 r._ensureLength(1); | |
| 274 r._used = 1; | 309 r._used = 1; |
| 275 r._digits[0] = 1; | 310 r._digits[0] = 1; |
| 311 r._digits[1] = 0; // Set leading zero for 64-bit processing. | |
| 276 } else { | 312 } else { |
| 277 // Set r to 0. | 313 // Set r to 0. |
| 278 r._neg = false; | 314 r._neg = false; |
| 279 r._used = 0; | 315 r._used = 0; |
| 280 } | 316 } |
| 281 return; | 317 return; |
| 282 } | 318 } |
| 283 r._ensureLength(r_used); | 319 r._ensureLength(r_used); |
| 284 var digits = _digits; | 320 var digits = _digits; |
| 285 var r_digits = r._digits; | 321 var r_digits = r._digits; |
| 286 var used = _used; | 322 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]; | 323 r_digits[i - n] = digits[i]; |
| 289 } | 324 } |
| 290 r._used = r_used; | 325 r._used = r_used; |
| 291 r._neg = _neg; | 326 r._neg = _neg; |
| 292 if (_neg) { | 327 if (_neg) { |
| 293 // Round down if any bit was shifted out. | 328 // Round down if any bit was shifted out. |
| 294 for (var i = 0; i < n; i++) { | 329 for (var i = 0; i < n; i++) { |
| 295 if (digits[i] != 0) { | 330 if (digits[i] != 0) { |
| 296 r._subTo(ONE, r); | 331 r._subTo(ONE, r); |
| 297 break; | 332 break; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 308 _dlShiftTo(ds, r); | 343 _dlShiftTo(ds, r); |
| 309 return; | 344 return; |
| 310 } | 345 } |
| 311 var cbs = DIGIT_BITS - bs; | 346 var cbs = DIGIT_BITS - bs; |
| 312 var bm = (1 << cbs) - 1; | 347 var bm = (1 << cbs) - 1; |
| 313 var r_used = _used + ds + 1; | 348 var r_used = _used + ds + 1; |
| 314 r._ensureLength(r_used); | 349 r._ensureLength(r_used); |
| 315 var digits = _digits; | 350 var digits = _digits; |
| 316 var r_digits = r._digits; | 351 var r_digits = r._digits; |
| 317 var c = 0; | 352 var c = 0; |
| 318 for (var i = _used - 1; i >= 0; --i) { | 353 var i = _used; |
| 354 while (--i >= 0) { | |
| 319 r_digits[i + ds + 1] = (digits[i] >> cbs) | c; | 355 r_digits[i + ds + 1] = (digits[i] >> cbs) | c; |
| 320 c = (digits[i] & bm) << bs; | 356 c = (digits[i] & bm) << bs; |
| 321 } | 357 } |
| 322 for (var i = ds - 1; i >= 0; --i) { | 358 i = ds; |
| 359 while (--i >= 0) { | |
| 323 r_digits[i] = 0; | 360 r_digits[i] = 0; |
| 324 } | 361 } |
| 325 r_digits[ds] = c; | 362 r_digits[ds] = c; |
| 326 r._used = r_used; | 363 r._used = r_used; |
| 327 r._neg = _neg; | 364 r._neg = _neg; |
| 328 r._clamp(); | 365 r._clamp(); |
| 329 } | 366 } |
| 330 | 367 |
| 331 // r = this >> n. | 368 // r = this >> n. |
| 332 void _rShiftTo(int n, _Bigint r) { | 369 void _rShiftTo(int n, _Bigint r) { |
| 333 var ds = n ~/ DIGIT_BITS; | 370 var ds = n ~/ DIGIT_BITS; |
| 334 var bs = n % DIGIT_BITS; | 371 var bs = n % DIGIT_BITS; |
| 335 if (bs == 0) { | 372 if (bs == 0) { |
| 336 _drShiftTo(ds, r); | 373 _drShiftTo(ds, r); |
| 337 return; | 374 return; |
| 338 } | 375 } |
| 339 var r_used = _used - ds; | 376 var r_used = _used - ds; |
| 340 if (r_used <= 0) { | 377 if (r_used <= 0) { |
| 341 if (_neg) { | 378 if (_neg) { |
| 342 // Set r to -1. | 379 // Set r to -1. |
| 343 r._neg = true; | 380 r._neg = true; |
| 381 r._used = 0; // No digits to preserve. | |
| 344 r._ensureLength(1); | 382 r._ensureLength(1); |
| 345 r._used = 1; | 383 r._used = 1; |
| 346 r._digits[0] = 1; | 384 r._digits[0] = 1; |
| 385 r._digits[1] = 0; // Set leading zero for 64-bit processing. | |
| 347 } else { | 386 } else { |
| 348 // Set r to 0. | 387 // Set r to 0. |
| 349 r._neg = false; | 388 r._neg = false; |
| 350 r._used = 0; | 389 r._used = 0; |
| 351 } | 390 } |
| 352 return; | 391 return; |
| 353 } | 392 } |
| 354 var cbs = DIGIT_BITS - bs; | 393 var cbs = DIGIT_BITS - bs; |
| 355 var bm = (1 << bs) - 1; | 394 var bm = (1 << bs) - 1; |
| 356 r._ensureLength(r_used); | 395 r._ensureLength(r_used); |
| 357 var digits = _digits; | 396 var digits = _digits; |
| 358 var r_digits = r._digits; | 397 var r_digits = r._digits; |
| 359 r_digits[0] = digits[ds] >> bs; | 398 r_digits[0] = digits[ds] >> bs; |
| 360 var used = _used; | 399 var used = _used; |
| 361 for (var i = ds + 1; i < used; ++i) { | 400 for (var i = ds + 1; i < used; i++) { |
| 362 r_digits[i - ds - 1] |= (digits[i] & bm) << cbs; | 401 r_digits[i - ds - 1] |= (digits[i] & bm) << cbs; |
| 363 r_digits[i - ds] = digits[i] >> bs; | 402 r_digits[i - ds] = digits[i] >> bs; |
| 364 } | 403 } |
| 365 r._neg = _neg; | 404 r._neg = _neg; |
| 366 r._used = r_used; | 405 r._used = r_used; |
| 367 r._clamp(); | 406 r._clamp(); |
| 368 if (_neg) { | 407 if (_neg) { |
| 369 // Round down if any bit was shifted out. | 408 // Round down if any bit was shifted out. |
| 370 if ((digits[ds] & bm) != 0) { | 409 if ((digits[ds] & bm) != 0) { |
| 371 r._subTo(ONE, r); | 410 r._subTo(ONE, r); |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 860 } else { | 899 } else { |
| 861 a_digits[i + used] = c; | 900 a_digits[i + used] = c; |
| 862 } | 901 } |
| 863 } | 902 } |
| 864 | 903 |
| 865 // r = this * a. | 904 // r = this * a. |
| 866 void _mulTo(_Bigint a, _Bigint r) { | 905 void _mulTo(_Bigint a, _Bigint r) { |
| 867 // TODO(regis): Use karatsuba multiplication when appropriate. | 906 // TODO(regis): Use karatsuba multiplication when appropriate. |
| 868 var used = _used; | 907 var used = _used; |
| 869 var a_used = a._used; | 908 var a_used = a._used; |
| 909 if (used == 0 || a_used == 0) { | |
| 910 r._used = 0; | |
| 911 r._neg = false; | |
| 912 return; | |
| 913 } | |
| 870 var r_used = used + a_used; | 914 var r_used = used + a_used; |
| 871 r._ensureLength(r_used); | 915 r._ensureLength(r_used); |
| 872 var digits = _digits; | 916 var digits = _digits; |
| 873 var a_digits = a._digits; | 917 var a_digits = a._digits; |
| 874 var r_digits = r._digits; | 918 var r_digits = r._digits; |
| 875 r._used = r_used; | 919 r._used = r_used; |
| 876 var i = r_used; | 920 var i = r_used + 1; // Set leading zero for 64-bit processing. |
| 877 while (--i >= 0) { | 921 while (--i >= 0) { |
| 878 r_digits[i] = 0; | 922 r_digits[i] = 0; |
| 879 } | 923 } |
| 880 for (i = 0; i < a_used; ++i) { | 924 for (i = 0; i < a_used; ++i) { |
| 881 _mulAdd(a_digits, i, digits, 0, r_digits, i, used); | 925 _mulAdd(a_digits, i, digits, 0, r_digits, i, used); |
| 882 } | 926 } |
| 883 r._clamp(); | 927 r._clamp(); |
| 884 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. | 928 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. |
| 885 } | 929 } |
| 886 | 930 |
| 887 // r = this^2, r != this. | 931 // r = this^2, r != this. |
| 888 void _sqrTo(_Bigint r) { | 932 void _sqrTo(_Bigint r) { |
| 889 var used = _used; | 933 var used = _used; |
| 934 if (used == 0) { | |
| 935 r._used = 0; | |
| 936 r._neg = false; | |
| 937 return; | |
| 938 } | |
| 890 var r_used = 2 * used; | 939 var r_used = 2 * used; |
| 891 r._ensureLength(r_used); | 940 r._ensureLength(r_used); |
| 892 var digits = _digits; | 941 var digits = _digits; |
| 893 var r_digits = r._digits; | 942 var r_digits = r._digits; |
| 894 var i = r_used; | 943 var i = r_used + 1; // Set leading zero for 64-bit processing. |
| 895 while (--i >= 0) { | 944 while (--i >= 0) { |
| 896 r_digits[i] = 0; | 945 r_digits[i] = 0; |
| 897 } | 946 } |
| 898 for (i = 0; i < used - 1; ++i) { | 947 for (i = 0; i < used - 1; ++i) { |
| 899 _sqrAdd(digits, i, r_digits, used); | 948 _sqrAdd(digits, i, r_digits, used); |
| 900 } | 949 } |
| 901 if (r_used > 0) { | 950 if (r_used > 0) { |
| 902 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1); | 951 _mulAdd(digits, i, digits, i, r_digits, 2*i, 1); |
| 903 } | 952 } |
| 904 r._used = r_used; | 953 r._used = r_used; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 963 var y_digits = y._digits; | 1012 var y_digits = y._digits; |
| 964 var yt = y_digits[y_used - 1]; | 1013 var yt = y_digits[y_used - 1]; |
| 965 if (yt == 0) return; | 1014 if (yt == 0) return; |
| 966 var i = r._used; | 1015 var i = r._used; |
| 967 var j = i - y_used; | 1016 var j = i - y_used; |
| 968 _Bigint t = (q == null) ? new _Bigint() : q; | 1017 _Bigint t = (q == null) ? new _Bigint() : q; |
| 969 y._dlShiftTo(j, t); | 1018 y._dlShiftTo(j, t); |
| 970 var r_digits = r._digits; | 1019 var r_digits = r._digits; |
| 971 if (r._compareTo(t) >= 0) { | 1020 if (r._compareTo(t) >= 0) { |
| 972 r_digits[r._used++] = 1; | 1021 r_digits[r._used++] = 1; |
| 1022 r_digits[r._used] = 0; // Set leading zero for 64-bit processing. | |
| 973 r._subTo(t, r); | 1023 r._subTo(t, r); |
| 974 } | 1024 } |
| 975 ONE._dlShiftTo(y_used, t); | 1025 ONE._dlShiftTo(y_used, t); |
| 976 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later. | 1026 t._subTo(y, y); // Negate y so we can replace sub with _mulAdd later. |
| 977 while (y._used < y_used) { | 1027 while (y._used < y_used) { |
| 978 y_digits[y._used++] = 0; | 1028 y_digits[y._used++] = 0; |
| 979 } | 1029 } |
| 1030 y_digits[y._used] = 0; // Set leading zero for 64-bit processing. | |
| 980 Uint32List args = new Uint32List(2); | 1031 Uint32List args = new Uint32List(2); |
| 981 args[_YT] = yt; | 1032 args[_YT] = yt; |
| 982 while (--j >= 0) { | 1033 while (--j >= 0) { |
| 983 _estQuotientDigit(args, r_digits, --i); | 1034 _estQuotientDigit(args, r_digits, --i); |
| 984 _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); | 1035 _mulAdd(args, _QD, y_digits, 0, r_digits, j, y_used); |
| 985 if (r_digits[i] < args[_QD]) { | 1036 if (r_digits[i] < args[_QD]) { |
| 986 y._dlShiftTo(j, t); | 1037 y._dlShiftTo(j, t); |
| 987 r._subTo(t, r); | 1038 r._subTo(t, r); |
| 988 while (r_digits[i] < --args[_QD]) { | 1039 while (r_digits[i] < --args[_QD]) { |
| 989 r._subTo(t, r); | 1040 r._subTo(t, r); |
| 990 } | 1041 } |
| 991 } | 1042 } |
| 992 } | 1043 } |
| 993 if (q != null) { | 1044 if (q != null) { |
| 994 r._drShiftTo(y_used, q); | 1045 r._drShiftTo(y_used, q); |
| 995 if (_neg != a._neg) { | 1046 if (_neg != a._neg && q._used > 0) { |
| 996 ZERO._subTo(q, q); | 1047 q._neg = !q._neg; |
| 997 } | 1048 } |
| 998 } | 1049 } |
| 999 r._used = y_used; | 1050 r._used = y_used; |
| 1000 r._clamp(); | 1051 r._clamp(); |
| 1001 if (nsh > 0) { | 1052 if (nsh > 0) { |
| 1002 r._rShiftTo(nsh, r); // Denormalize remainder. | 1053 r._rShiftTo(nsh, r); // Denormalize remainder. |
| 1003 } | 1054 } |
| 1004 if (_neg) { | 1055 if (_neg && r._used > 0) { |
| 1005 ZERO._subTo(r, r); | 1056 r._neg = !r._neg; |
| 1006 } | 1057 } |
| 1007 } | 1058 } |
| 1008 | 1059 |
| 1009 int get _identityHashCode { | 1060 int get _identityHashCode { |
| 1010 return this; | 1061 return this; |
| 1011 } | 1062 } |
| 1012 int operator ~() { | 1063 int operator ~() { |
| 1013 _Bigint result = new _Bigint(); | 1064 _Bigint result = new _Bigint(); |
| 1014 _notTo(result); | 1065 _notTo(result); |
| 1015 return result._toValidInt(); | 1066 return result._toValidInt(); |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1412 return r; | 1463 return r; |
| 1413 } | 1464 } |
| 1414 | 1465 |
| 1415 // x = x/R mod _m | 1466 // x = x/R mod _m |
| 1416 void _reduce(_Bigint x) { | 1467 void _reduce(_Bigint x) { |
| 1417 x._ensureLength(_mused2 + 1); | 1468 x._ensureLength(_mused2 + 1); |
| 1418 var x_digits = x._digits; | 1469 var x_digits = x._digits; |
| 1419 while (x._used <= _mused2) { // Pad x so _mulAdd has enough room later. | 1470 while (x._used <= _mused2) { // Pad x so _mulAdd has enough room later. |
| 1420 x_digits[x._used++] = 0; | 1471 x_digits[x._used++] = 0; |
| 1421 } | 1472 } |
| 1473 x_digits[x._used] = 0; // Set leading zero for 64-bit processing. | |
| 1422 var m_used = _m._used; | 1474 var m_used = _m._used; |
| 1423 var m_digits = _m._digits; | 1475 var m_digits = _m._digits; |
| 1424 for (var i = 0; i < m_used; ++i) { | 1476 for (var i = 0; i < m_used; i++) { |
| 1425 _mulMod(_rho_mu, x_digits, i); | 1477 _mulMod(_rho_mu, x_digits, i); |
| 1426 _Bigint._mulAdd(_rho_mu, _MU, m_digits, 0, x_digits, i, m_used); | 1478 _Bigint._mulAdd(_rho_mu, _MU, m_digits, 0, x_digits, i, m_used); |
| 1427 } | 1479 } |
| 1428 x._clamp(); | 1480 x._clamp(); |
| 1429 x._drShiftTo(m_used, x); | 1481 x._drShiftTo(m_used, x); |
| 1430 if (x._compareTo(_m) >= 0) { | 1482 if (x._compareTo(_m) >= 0) { |
| 1431 x._subTo(_m, x); | 1483 x._subTo(_m, x); |
| 1432 } | 1484 } |
| 1433 } | 1485 } |
| 1434 | 1486 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1476 void _sqrTo(_Bigint x, _Bigint r) { | 1528 void _sqrTo(_Bigint x, _Bigint r) { |
| 1477 x._sqrTo(r); | 1529 x._sqrTo(r); |
| 1478 _reduce(r); | 1530 _reduce(r); |
| 1479 } | 1531 } |
| 1480 | 1532 |
| 1481 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { | 1533 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { |
| 1482 x._mulTo(y, r); | 1534 x._mulTo(y, r); |
| 1483 _reduce(r); | 1535 _reduce(r); |
| 1484 } | 1536 } |
| 1485 } | 1537 } |
| OLD | NEW |