| 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 | 119 |
| 120 // Initialize instance to the given hex string. | 120 // Initialize instance to the given hex string. |
| 121 // TODO(regis): Copy Bigint::NewFromHexCString, fewer digit accesses. | 121 // TODO(regis): Copy Bigint::NewFromHexCString, fewer digit accesses. |
| 122 // TODO(regis): Unused. | 122 // TODO(regis): Unused. |
| 123 _Bigint _setHex(String s) { | 123 _Bigint _setHex(String s) { |
| 124 const int HEX_BITS = 4; | 124 const int HEX_BITS = 4; |
| 125 const int HEX_DIGITS_PER_DIGIT = 8; | 125 const int HEX_DIGITS_PER_DIGIT = 8; |
| 126 var hexDigitIndex = s.length; | 126 var hexDigitIndex = s.length; |
| 127 _ensureLength((hexDigitIndex + HEX_DIGITS_PER_DIGIT - 1) ~/ HEX_DIGITS_PER_D
IGIT); | 127 _ensureLength((hexDigitIndex + HEX_DIGITS_PER_DIGIT - 1) ~/ HEX_DIGITS_PER_D
IGIT); |
| 128 var bitIndex = 0; | 128 var bitIndex = 0; |
| 129 var digits = _digits; |
| 129 while (--hexDigitIndex >= 0) { | 130 while (--hexDigitIndex >= 0) { |
| 130 var digit = DIGIT_TABLE[s.codeUnitAt(hexDigitIndex)]; | 131 var digit = DIGIT_TABLE[s.codeUnitAt(hexDigitIndex)]; |
| 131 if (digit = null) { | 132 if (digit = null) { |
| 132 if (s[hexDigitIndex] == "-") _neg = true; | 133 if (s[hexDigitIndex] == "-") _neg = true; |
| 133 continue; // Ignore invalid digits. | 134 continue; // Ignore invalid digits. |
| 134 } | 135 } |
| 135 _neg = false; // Ignore "-" if not at index 0. | 136 _neg = false; // Ignore "-" if not at index 0. |
| 136 if (bitIndex == 0) { | 137 if (bitIndex == 0) { |
| 137 _digits[_used++] = digit; | 138 digits[_used++] = digit; |
| 138 // TODO(regis): What if too many bad digits were ignored and | 139 // TODO(regis): What if too many bad digits were ignored and |
| 139 // _used becomes larger than _digits.length? error or reallocate? | 140 // _used becomes larger than _digits.length? error or reallocate? |
| 140 } else { | 141 } else { |
| 141 _digits[_used - 1] |= digit << bitIndex; | 142 digits[_used - 1] |= digit << bitIndex; |
| 142 } | 143 } |
| 143 bitIndex = (bitIndex + HEX_BITS) % DIGIT_BITS; | 144 bitIndex = (bitIndex + HEX_BITS) % DIGIT_BITS; |
| 144 } | 145 } |
| 145 _clamp(); | 146 _clamp(); |
| 146 return this; | 147 return this; |
| 147 } | 148 } |
| 148 | 149 |
| 149 // Initialize instance to the given double value. | 150 // Initialize instance to the given double value. |
| 150 _Bigint _setDouble(int sign, int significand, int exponent) { | 151 _Bigint _setDouble(int sign, int significand, int exponent) { |
| 151 assert(significand >= 0); | 152 assert(significand >= 0); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 168 for(value = 10; value < 36; ++value) table[digit++] = value; | 169 for(value = 10; value < 36; ++value) table[digit++] = value; |
| 169 digit = "A".codeUnitAt(0); | 170 digit = "A".codeUnitAt(0); |
| 170 for(value = 10; value < 36; ++value) table[digit++] = value; | 171 for(value = 10; value < 36; ++value) table[digit++] = value; |
| 171 return table; | 172 return table; |
| 172 } | 173 } |
| 173 | 174 |
| 174 // Return most compact integer (i.e. possibly Smi or Mint). | 175 // Return most compact integer (i.e. possibly Smi or Mint). |
| 175 // TODO(regis): Intrinsify. | 176 // TODO(regis): Intrinsify. |
| 176 int _toValidInt() { | 177 int _toValidInt() { |
| 177 assert(DIGIT_BITS == 32); // Otherwise this code needs to be revised. | 178 assert(DIGIT_BITS == 32); // Otherwise this code needs to be revised. |
| 178 if (_used == 0) return 0; | 179 var used = _used; |
| 179 if (_used == 1) return _neg ? -_digits[0] : _digits[0]; | 180 if (used == 0) return 0; |
| 180 if (_used > 2) return this; | 181 var digits = _digits; |
| 182 if (used == 1) return _neg ? -digits[0] : digits[0]; |
| 183 if (used > 2) return this; |
| 181 if (_neg) { | 184 if (_neg) { |
| 182 if (_digits[1] > 0x80000000) return this; | 185 if (digits[1] > 0x80000000) return this; |
| 183 if (_digits[1] == 0x80000000) { | 186 if (digits[1] == 0x80000000) { |
| 184 if (_digits[0] > 0) return this; | 187 if (digits[0] > 0) return this; |
| 185 return MIN_INT64; | 188 return MIN_INT64; |
| 186 } | 189 } |
| 187 return -((_digits[1] << DIGIT_BITS) | _digits[0]); | 190 return -((digits[1] << DIGIT_BITS) | digits[0]); |
| 188 } | 191 } |
| 189 if (_digits[1] >= 0x80000000) return this; | 192 if (digits[1] >= 0x80000000) return this; |
| 190 return (_digits[1] << DIGIT_BITS) | _digits[0]; | 193 return (digits[1] << DIGIT_BITS) | digits[0]; |
| 191 } | 194 } |
| 192 | 195 |
| 193 // Conversion from int to bigint. | 196 // Conversion from int to bigint. |
| 194 _Bigint _toBigint() => this; | 197 _Bigint _toBigint() => this; |
| 195 | 198 |
| 196 // Make sure at least 'length' _digits are allocated. | 199 // Make sure at least 'length' _digits are allocated. |
| 197 // Copy existing _digits if reallocation is necessary. | 200 // Copy existing _digits if reallocation is necessary. |
| 198 // TODO(regis): Check that we are not preserving _digits unnecessarily. | 201 // TODO(regis): Check that we are not preserving _digits unnecessarily. |
| 199 void _ensureLength(int length) { | 202 void _ensureLength(int length) { |
| 200 if (length > 0 && (_digits == null || length > _digits.length)) { | 203 var digits = _digits; |
| 204 if (length > 0 && (digits == null || length > digits.length)) { |
| 201 var new_digits = new Uint32List(length + EXTRA_DIGITS); | 205 var new_digits = new Uint32List(length + EXTRA_DIGITS); |
| 202 if (_digits != null) { | 206 if (digits != null) { |
| 203 for (var i = _used; --i >= 0; ) { | 207 for (var i = _used; --i >= 0; ) { |
| 204 new_digits[i] = _digits[i]; | 208 new_digits[i] = digits[i]; |
| 205 } | 209 } |
| 206 } | 210 } |
| 207 _digits = new_digits; | 211 _digits = new_digits; |
| 208 } | 212 } |
| 209 } | 213 } |
| 210 | 214 |
| 211 // Clamp off excess high _digits. | 215 // Clamp off excess high _digits. |
| 212 void _clamp() { | 216 void _clamp() { |
| 213 while (_used > 0 && _digits[_used - 1] == 0) { | 217 var digits = _digits; |
| 218 while (_used > 0 && digits[_used - 1] == 0) { |
| 214 --_used; | 219 --_used; |
| 215 } | 220 } |
| 216 assert(_used > 0 || !_neg); | |
| 217 } | 221 } |
| 218 | 222 |
| 219 // Copy this to r. | 223 // Copy this to r. |
| 220 void _copyTo(_Bigint r) { | 224 void _copyTo(_Bigint r) { |
| 221 r._ensureLength(_used); | 225 r._ensureLength(_used); |
| 226 var digits = _digits; |
| 227 var r_digits = r._digits; |
| 222 for (var i = _used - 1; i >= 0; --i) { | 228 for (var i = _used - 1; i >= 0; --i) { |
| 223 r._digits[i] = _digits[i]; | 229 r_digits[i] = digits[i]; |
| 224 } | 230 } |
| 225 r._used = _used; | 231 r._used = _used; |
| 226 r._neg = _neg; | 232 r._neg = _neg; |
| 227 } | 233 } |
| 228 | 234 |
| 229 // Return the bit length of digit x. | 235 // Return the bit length of digit x. |
| 230 int _nbits(int x) { | 236 int _nbits(int x) { |
| 231 var r = 1, t; | 237 var r = 1, t; |
| 232 if ((t = x >> 16) != 0) { x = t; r += 16; } | 238 if ((t = x >> 16) != 0) { x = t; r += 16; } |
| 233 if ((t = x >> 8) != 0) { x = t; r += 8; } | 239 if ((t = x >> 8) != 0) { x = t; r += 8; } |
| 234 if ((t = x >> 4) != 0) { x = t; r += 4; } | 240 if ((t = x >> 4) != 0) { x = t; r += 4; } |
| 235 if ((t = x >> 2) != 0) { x = t; r += 2; } | 241 if ((t = x >> 2) != 0) { x = t; r += 2; } |
| 236 if ((x >> 1) != 0) { r += 1; } | 242 if ((x >> 1) != 0) { r += 1; } |
| 237 return r; | 243 return r; |
| 238 } | 244 } |
| 239 | 245 |
| 240 // r = this << n*DIGIT_BITS. | 246 // r = this << n*DIGIT_BITS. |
| 241 void _dlShiftTo(int n, _Bigint r) { | 247 void _dlShiftTo(int n, _Bigint r) { |
| 242 var r_used = _used + n; | 248 var r_used = _used + n; |
| 243 r._ensureLength(r_used); | 249 r._ensureLength(r_used); |
| 250 var digits = _digits; |
| 251 var r_digits = r._digits; |
| 244 for (var i = _used - 1; i >= 0; --i) { | 252 for (var i = _used - 1; i >= 0; --i) { |
| 245 r._digits[i + n] = _digits[i]; | 253 r_digits[i + n] = digits[i]; |
| 246 } | 254 } |
| 247 for (var i = n - 1; i >= 0; --i) { | 255 for (var i = n - 1; i >= 0; --i) { |
| 248 r._digits[i] = 0; | 256 r_digits[i] = 0; |
| 249 } | 257 } |
| 250 r._used = r_used; | 258 r._used = r_used; |
| 251 r._neg = _neg; | 259 r._neg = _neg; |
| 252 } | 260 } |
| 253 | 261 |
| 254 // r = this >> n*DIGIT_BITS. | 262 // r = this >> n*DIGIT_BITS. |
| 255 void _drShiftTo(int n, _Bigint r) { | 263 void _drShiftTo(int n, _Bigint r) { |
| 256 var r_used = _used - n; | 264 var r_used = _used - n; |
| 257 if (r_used < 0) { | 265 if (r_used < 0) { |
| 258 if (_neg) { | 266 if (_neg) { |
| 259 // Set r to -1. | 267 // Set r to -1. |
| 260 r._neg = true; | 268 r._neg = true; |
| 261 r._ensureLength(1); | 269 r._ensureLength(1); |
| 262 r._used = 1; | 270 r._used = 1; |
| 263 r._digits[0] = 1; | 271 r._digits[0] = 1; |
| 264 } else { | 272 } else { |
| 265 // Set r to 0. | 273 // Set r to 0. |
| 266 r._neg = false; | 274 r._neg = false; |
| 267 r._used = 0; | 275 r._used = 0; |
| 268 } | 276 } |
| 269 return; | 277 return; |
| 270 } | 278 } |
| 271 r._ensureLength(r_used); | 279 r._ensureLength(r_used); |
| 272 for (var i = n; i < _used; ++i) { | 280 var digits = _digits; |
| 273 r._digits[i - n] = _digits[i]; | 281 var r_digits = r._digits; |
| 282 var used = _used; |
| 283 for (var i = n; i < used; ++i) { |
| 284 r_digits[i - n] = digits[i]; |
| 274 } | 285 } |
| 275 r._used = r_used; | 286 r._used = r_used; |
| 276 r._neg = _neg; | 287 r._neg = _neg; |
| 277 if (_neg) { | 288 if (_neg) { |
| 278 // Round down if any bit was shifted out. | 289 // Round down if any bit was shifted out. |
| 279 for (var i = 0; i < n; i++) { | 290 for (var i = 0; i < n; i++) { |
| 280 if (_digits[i] != 0) { | 291 if (digits[i] != 0) { |
| 281 r._subTo(ONE, r); | 292 r._subTo(ONE, r); |
| 282 break; | 293 break; |
| 283 } | 294 } |
| 284 } | 295 } |
| 285 } | 296 } |
| 286 } | 297 } |
| 287 | 298 |
| 288 // r = this << n. | 299 // r = this << n. |
| 289 void _lShiftTo(int n, _Bigint r) { | 300 void _lShiftTo(int n, _Bigint r) { |
| 290 var ds = n ~/ DIGIT_BITS; | 301 var ds = n ~/ DIGIT_BITS; |
| 291 var bs = n % DIGIT_BITS; | 302 var bs = n % DIGIT_BITS; |
| 292 if (bs == 0) { | 303 if (bs == 0) { |
| 293 _dlShiftTo(ds, r); | 304 _dlShiftTo(ds, r); |
| 294 return; | 305 return; |
| 295 } | 306 } |
| 296 var cbs = DIGIT_BITS - bs; | 307 var cbs = DIGIT_BITS - bs; |
| 297 var bm = (1 << cbs) - 1; | 308 var bm = (1 << cbs) - 1; |
| 298 var r_used = _used + ds + 1; | 309 var r_used = _used + ds + 1; |
| 299 r._ensureLength(r_used); | 310 r._ensureLength(r_used); |
| 311 var digits = _digits; |
| 312 var r_digits = r._digits; |
| 300 var c = 0; | 313 var c = 0; |
| 301 for (var i = _used - 1; i >= 0; --i) { | 314 for (var i = _used - 1; i >= 0; --i) { |
| 302 r._digits[i + ds + 1] = (_digits[i] >> cbs) | c; | 315 r_digits[i + ds + 1] = (digits[i] >> cbs) | c; |
| 303 c = (_digits[i] & bm) << bs; | 316 c = (digits[i] & bm) << bs; |
| 304 } | 317 } |
| 305 for (var i = ds - 1; i >= 0; --i) { | 318 for (var i = ds - 1; i >= 0; --i) { |
| 306 r._digits[i] = 0; | 319 r_digits[i] = 0; |
| 307 } | 320 } |
| 308 r._digits[ds] = c; | 321 r_digits[ds] = c; |
| 309 r._used = r_used; | 322 r._used = r_used; |
| 310 r._neg = _neg; | 323 r._neg = _neg; |
| 311 r._clamp(); | 324 r._clamp(); |
| 312 } | 325 } |
| 313 | 326 |
| 314 // r = this >> n. | 327 // r = this >> n. |
| 315 void _rShiftTo(int n, _Bigint r) { | 328 void _rShiftTo(int n, _Bigint r) { |
| 316 var ds = n ~/ DIGIT_BITS; | 329 var ds = n ~/ DIGIT_BITS; |
| 317 var bs = n % DIGIT_BITS; | 330 var bs = n % DIGIT_BITS; |
| 318 if (bs == 0) { | 331 if (bs == 0) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 330 } else { | 343 } else { |
| 331 // Set r to 0. | 344 // Set r to 0. |
| 332 r._neg = false; | 345 r._neg = false; |
| 333 r._used = 0; | 346 r._used = 0; |
| 334 } | 347 } |
| 335 return; | 348 return; |
| 336 } | 349 } |
| 337 var cbs = DIGIT_BITS - bs; | 350 var cbs = DIGIT_BITS - bs; |
| 338 var bm = (1 << bs) - 1; | 351 var bm = (1 << bs) - 1; |
| 339 r._ensureLength(r_used); | 352 r._ensureLength(r_used); |
| 340 r._digits[0] = _digits[ds] >> bs; | 353 var digits = _digits; |
| 341 for (var i = ds + 1; i < _used; ++i) { | 354 var r_digits = r._digits; |
| 342 r._digits[i - ds - 1] |= (_digits[i] & bm) << cbs; | 355 r_digits[0] = digits[ds] >> bs; |
| 343 r._digits[i - ds] = _digits[i] >> bs; | 356 var used = _used; |
| 357 for (var i = ds + 1; i < used; ++i) { |
| 358 r_digits[i - ds - 1] |= (digits[i] & bm) << cbs; |
| 359 r_digits[i - ds] = digits[i] >> bs; |
| 344 } | 360 } |
| 345 r._neg = _neg; | 361 r._neg = _neg; |
| 346 r._used = r_used; | 362 r._used = r_used; |
| 347 r._clamp(); | 363 r._clamp(); |
| 348 if (_neg) { | 364 if (_neg) { |
| 349 // Round down if any bit was shifted out. | 365 // Round down if any bit was shifted out. |
| 350 if ((_digits[ds] & bm) != 0) { | 366 if ((digits[ds] & bm) != 0) { |
| 351 r._subTo(ONE, r); | 367 r._subTo(ONE, r); |
| 352 return; | 368 return; |
| 353 } | 369 } |
| 354 for (var i = 0; i < ds; i++) { | 370 for (var i = 0; i < ds; i++) { |
| 355 if (_digits[i] != 0) { | 371 if (digits[i] != 0) { |
| 356 r._subTo(ONE, r); | 372 r._subTo(ONE, r); |
| 357 return; | 373 return; |
| 358 } | 374 } |
| 359 } | 375 } |
| 360 } | 376 } |
| 361 } | 377 } |
| 362 | 378 |
| 363 // Return 0 if abs(this) == abs(a). | 379 // Return 0 if abs(this) == abs(a). |
| 364 // Return a positive number if abs(this) > abs(a). | 380 // Return a positive number if abs(this) > abs(a). |
| 365 // Return a negative number if abs(this) < abs(a). | 381 // Return a negative number if abs(this) < abs(a). |
| 366 int _absCompareTo(_Bigint a) { | 382 int _absCompareTo(_Bigint a) { |
| 367 var r = _used - a._used; | 383 var r = _used - a._used; |
| 368 if (r == 0) { | 384 if (r == 0) { |
| 369 var i = _used; | 385 var i = _used; |
| 370 while (--i >= 0 && (r = _digits[i] - a._digits[i]) == 0); | 386 var digits = _digits; |
| 387 var a_digits = a._digits; |
| 388 while (--i >= 0 && (r = digits[i] - a_digits[i]) == 0); |
| 371 } | 389 } |
| 372 return r; | 390 return r; |
| 373 } | 391 } |
| 374 | 392 |
| 375 // Return 0 if this == a. | 393 // Return 0 if this == a. |
| 376 // Return a positive number if this > a. | 394 // Return a positive number if this > a. |
| 377 // Return a negative number if this < a. | 395 // Return a negative number if this < a. |
| 378 int _compareTo(_Bigint a) { | 396 int _compareTo(_Bigint a) { |
| 379 var r; | 397 var r; |
| 380 if (_neg == a._neg) { | 398 if (_neg == a._neg) { |
| 381 r = _absCompareTo(a); | 399 r = _absCompareTo(a); |
| 382 if (_neg) { | 400 if (_neg) { |
| 383 r = -r; | 401 r = -r; |
| 384 } | 402 } |
| 385 } else if (_neg) { | 403 } else if (_neg) { |
| 386 r = -1; | 404 r = -1; |
| 387 } else { | 405 } else { |
| 388 r = 1; | 406 r = 1; |
| 389 } | 407 } |
| 390 return r; | 408 return r; |
| 391 } | 409 } |
| 392 | 410 |
| 393 // r = abs(this) + abs(a). | 411 // r = abs(this) + abs(a). |
| 394 void _absAddTo(_Bigint a, _Bigint r) { | 412 void _absAddTo(_Bigint a, _Bigint r) { |
| 395 if (_used < a._used) { | 413 var used = _used; |
| 414 var a_used = a._used; |
| 415 if (used < a_used) { |
| 396 a._absAddTo(this, r); | 416 a._absAddTo(this, r); |
| 397 return; | 417 return; |
| 398 } | 418 } |
| 399 if (_used == 0) { | 419 if (used == 0) { |
| 400 // Set r to 0. | 420 // Set r to 0. |
| 401 r._neg = false; | 421 r._neg = false; |
| 402 r._used = 0; | 422 r._used = 0; |
| 403 return; | 423 return; |
| 404 } | 424 } |
| 405 if (a._used == 0) { | 425 if (a_used == 0) { |
| 406 _copyTo(r); | 426 _copyTo(r); |
| 407 return; | 427 return; |
| 408 } | 428 } |
| 409 r._ensureLength(_used + 1); | 429 r._ensureLength(used + 1); |
| 430 var digits = _digits; |
| 431 var a_digits = a._digits; |
| 432 var r_digits = r._digits; |
| 410 var c = 0; | 433 var c = 0; |
| 411 for (var i = 0; i < a._used; i++) { | 434 for (var i = 0; i < a_used; i++) { |
| 412 c += _digits[i] + a._digits[i]; | 435 c += digits[i] + a_digits[i]; |
| 413 r._digits[i] = c & DIGIT_MASK; | 436 r_digits[i] = c & DIGIT_MASK; |
| 414 c >>= DIGIT_BITS; | 437 c >>= DIGIT_BITS; |
| 415 } | 438 } |
| 416 for (var i = a._used; i < _used; i++) { | 439 for (var i = a_used; i < used; i++) { |
| 417 c += _digits[i]; | 440 c += digits[i]; |
| 418 r._digits[i] = c & DIGIT_MASK; | 441 r_digits[i] = c & DIGIT_MASK; |
| 419 c >>= DIGIT_BITS; | 442 c >>= DIGIT_BITS; |
| 420 } | 443 } |
| 421 r._digits[_used] = c; | 444 r_digits[used] = c; |
| 422 r._used = _used + 1; | 445 r._used = used + 1; |
| 423 r._clamp(); | 446 r._clamp(); |
| 424 } | 447 } |
| 425 | 448 |
| 426 // r = abs(this) - abs(a), with abs(this) >= abs(a). | 449 // r = abs(this) - abs(a), with abs(this) >= abs(a). |
| 427 void _absSubTo(_Bigint a, _Bigint r) { | 450 void _absSubTo(_Bigint a, _Bigint r) { |
| 428 assert(_absCompareTo(a) >= 0); | 451 assert(_absCompareTo(a) >= 0); |
| 429 if (_used == 0) { | 452 var used = _used; |
| 453 if (used == 0) { |
| 430 // Set r to 0. | 454 // Set r to 0. |
| 431 r._neg = false; | 455 r._neg = false; |
| 432 r._used = 0; | 456 r._used = 0; |
| 433 return; | 457 return; |
| 434 } | 458 } |
| 435 if (a._used == 0) { | 459 var a_used = a._used; |
| 460 if (a_used == 0) { |
| 436 _copyTo(r); | 461 _copyTo(r); |
| 437 return; | 462 return; |
| 438 } | 463 } |
| 439 r._ensureLength(_used); | 464 r._ensureLength(used); |
| 465 var digits = _digits; |
| 466 var a_digits = a._digits; |
| 467 var r_digits = r._digits; |
| 440 var c = 0; | 468 var c = 0; |
| 441 for (var i = 0; i < a._used; i++) { | 469 for (var i = 0; i < a_used; i++) { |
| 442 c += _digits[i] - a._digits[i]; | 470 c += digits[i] - a_digits[i]; |
| 443 r._digits[i] = c & DIGIT_MASK; | 471 r_digits[i] = c & DIGIT_MASK; |
| 444 c >>= DIGIT_BITS; | 472 c >>= DIGIT_BITS; |
| 445 } | 473 } |
| 446 for (var i = a._used; i < _used; i++) { | 474 for (var i = a_used; i < used; i++) { |
| 447 c += _digits[i]; | 475 c += digits[i]; |
| 448 r._digits[i] = c & DIGIT_MASK; | 476 r_digits[i] = c & DIGIT_MASK; |
| 449 c >>= DIGIT_BITS; | 477 c >>= DIGIT_BITS; |
| 450 } | 478 } |
| 451 r._used = _used; | 479 r._used = used; |
| 452 r._clamp(); | 480 r._clamp(); |
| 453 } | 481 } |
| 454 | 482 |
| 455 // r = abs(this) & abs(a). | 483 // r = abs(this) & abs(a). |
| 456 void _absAndTo(_Bigint a, _Bigint r) { | 484 void _absAndTo(_Bigint a, _Bigint r) { |
| 457 var r_used = (_used < a._used) ? _used : a._used; | 485 var r_used = (_used < a._used) ? _used : a._used; |
| 458 r._ensureLength(r_used); | 486 r._ensureLength(r_used); |
| 487 var digits = _digits; |
| 488 var a_digits = a._digits; |
| 489 var r_digits = r._digits; |
| 459 for (var i = 0; i < r_used; i++) { | 490 for (var i = 0; i < r_used; i++) { |
| 460 r._digits[i] = _digits[i] & a._digits[i]; | 491 r_digits[i] = digits[i] & a_digits[i]; |
| 461 } | 492 } |
| 462 r._used = r_used; | 493 r._used = r_used; |
| 463 r._clamp(); | 494 r._clamp(); |
| 464 } | 495 } |
| 465 | 496 |
| 466 // r = abs(this) &~ abs(a). | 497 // r = abs(this) &~ abs(a). |
| 467 void _absAndNotTo(_Bigint a, _Bigint r) { | 498 void _absAndNotTo(_Bigint a, _Bigint r) { |
| 468 var r_used = _used; | 499 var r_used = _used; |
| 469 r._ensureLength(r_used); | 500 r._ensureLength(r_used); |
| 501 var digits = _digits; |
| 502 var a_digits = a._digits; |
| 503 var r_digits = r._digits; |
| 470 var m = (r_used < a._used) ? r_used : a._used; | 504 var m = (r_used < a._used) ? r_used : a._used; |
| 471 for (var i = 0; i < m; i++) { | 505 for (var i = 0; i < m; i++) { |
| 472 r._digits[i] = _digits[i] &~ a._digits[i]; | 506 r_digits[i] = digits[i] &~ a_digits[i]; |
| 473 } | 507 } |
| 474 for (var i = m; i < r_used; i++) { | 508 for (var i = m; i < r_used; i++) { |
| 475 r._digits[i] = _digits[i]; | 509 r_digits[i] = digits[i]; |
| 476 } | 510 } |
| 477 r._used = r_used; | 511 r._used = r_used; |
| 478 r._clamp(); | 512 r._clamp(); |
| 479 } | 513 } |
| 480 | 514 |
| 481 // r = abs(this) | abs(a). | 515 // r = abs(this) | abs(a). |
| 482 void _absOrTo(_Bigint a, _Bigint r) { | 516 void _absOrTo(_Bigint a, _Bigint r) { |
| 483 var r_used = (_used > a._used) ? _used : a._used; | 517 var used = _used; |
| 518 var a_used = a._used; |
| 519 var r_used = (used > a_used) ? used : a_used; |
| 484 r._ensureLength(r_used); | 520 r._ensureLength(r_used); |
| 521 var digits = _digits; |
| 522 var a_digits = a._digits; |
| 523 var r_digits = r._digits; |
| 485 var l, m; | 524 var l, m; |
| 486 if (_used < a._used) { | 525 if (used < a_used) { |
| 487 l = a; | 526 l = a; |
| 488 m = _used; | 527 m = used; |
| 489 } else { | 528 } else { |
| 490 l = this; | 529 l = this; |
| 491 m = a._used; | 530 m = a_used; |
| 492 } | 531 } |
| 493 for (var i = 0; i < m; i++) { | 532 for (var i = 0; i < m; i++) { |
| 494 r._digits[i] = _digits[i] | a._digits[i]; | 533 r_digits[i] = digits[i] | a_digits[i]; |
| 495 } | 534 } |
| 535 var l_digits = l._digits; |
| 496 for (var i = m; i < r_used; i++) { | 536 for (var i = m; i < r_used; i++) { |
| 497 r._digits[i] = l._digits[i]; | 537 r_digits[i] = l_digits[i]; |
| 498 } | 538 } |
| 499 r._used = r_used; | 539 r._used = r_used; |
| 500 r._clamp(); | 540 r._clamp(); |
| 501 } | 541 } |
| 502 | 542 |
| 503 // r = abs(this) ^ abs(a). | 543 // r = abs(this) ^ abs(a). |
| 504 void _absXorTo(_Bigint a, _Bigint r) { | 544 void _absXorTo(_Bigint a, _Bigint r) { |
| 505 var r_used = (_used > a._used) ? _used : a._used; | 545 var used = _used; |
| 546 var a_used = a._used; |
| 547 var r_used = (used > a_used) ? used : a_used; |
| 506 r._ensureLength(r_used); | 548 r._ensureLength(r_used); |
| 549 var digits = _digits; |
| 550 var a_digits = a._digits; |
| 551 var r_digits = r._digits; |
| 507 var l, m; | 552 var l, m; |
| 508 if (_used < a._used) { | 553 if (used < a_used) { |
| 509 l = a; | 554 l = a; |
| 510 m = _used; | 555 m = used; |
| 511 } else { | 556 } else { |
| 512 l = this; | 557 l = this; |
| 513 m = a._used; | 558 m = a_used; |
| 514 } | 559 } |
| 515 for (var i = 0; i < m; i++) { | 560 for (var i = 0; i < m; i++) { |
| 516 r._digits[i] = _digits[i] ^ a._digits[i]; | 561 r_digits[i] = digits[i] ^ a_digits[i]; |
| 517 } | 562 } |
| 563 var l_digits = l._digits; |
| 518 for (var i = m; i < r_used; i++) { | 564 for (var i = m; i < r_used; i++) { |
| 519 r._digits[i] = l._digits[i]; | 565 r_digits[i] = l_digits[i]; |
| 520 } | 566 } |
| 521 r._used = r_used; | 567 r._used = r_used; |
| 522 r._clamp(); | 568 r._clamp(); |
| 523 } | 569 } |
| 524 | 570 |
| 525 // Return r = this & a. | 571 // Return r = this & a. |
| 526 _Bigint _andTo(_Bigint a, _Bigint r) { | 572 _Bigint _andTo(_Bigint a, _Bigint r) { |
| 527 if (_neg == a._neg) { | 573 if (_neg == a._neg) { |
| 528 if (_neg) { | 574 if (_neg) { |
| 529 // (-this) & (-a) == ~(this-1) & ~(a-1) | 575 // (-this) & (-a) == ~(this-1) & ~(a-1) |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 // w[j..j+n-1] += this[i..i+n-1] * x. | 781 // w[j..j+n-1] += this[i..i+n-1] * x. |
| 736 // Returns carry out. | 782 // Returns carry out. |
| 737 int _am(int i, int x, _Bigint w, int j, int n) { | 783 int _am(int i, int x, _Bigint w, int j, int n) { |
| 738 if (x == 0) { | 784 if (x == 0) { |
| 739 // No-op if x is 0. | 785 // No-op if x is 0. |
| 740 return 0; | 786 return 0; |
| 741 } | 787 } |
| 742 int c = 0; | 788 int c = 0; |
| 743 int xl = x & DIGIT2_MASK; | 789 int xl = x & DIGIT2_MASK; |
| 744 int xh = x >> DIGIT2_BITS; | 790 int xh = x >> DIGIT2_BITS; |
| 791 var digits = _digits; |
| 792 var w_digits = w._digits; |
| 745 while (--n >= 0) { | 793 while (--n >= 0) { |
| 746 int l = _digits[i] & DIGIT2_MASK; | 794 int l = digits[i] & DIGIT2_MASK; |
| 747 int h = _digits[i++] >> DIGIT2_BITS; | 795 int h = digits[i++] >> DIGIT2_BITS; |
| 748 int m = xh*l + h*xl; | 796 int m = xh*l + h*xl; |
| 749 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + w._digits[j] + c; | 797 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + w_digits[j] + c; |
| 750 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; | 798 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; |
| 751 w._digits[j++] = l & DIGIT_MASK; | 799 w_digits[j++] = l & DIGIT_MASK; |
| 752 } | 800 } |
| 753 return c; | 801 return c; |
| 754 } | 802 } |
| 755 | 803 |
| 756 // Accumulate multiply with carry. | 804 // Accumulate multiply with carry. |
| 757 // this[i..i+n-1]: bigint multiplicand. | 805 // this[i..i+n-1]: bigint multiplicand. |
| 758 // x: digit multiplier, 0 <= x < 2*DIGIT_BASE (i.e. 33-bit multiplier). | 806 // x: digit multiplier, 0 <= x < 2*DIGIT_BASE (i.e. 33-bit multiplier). |
| 759 // w[j..j+n-1]: bigint accumulator. | 807 // w[j..j+n-1]: bigint accumulator. |
| 760 // c: int carry in. | 808 // c: int carry in. |
| 761 // Returns carry out. | 809 // Returns carry out. |
| 762 // w[j..j+n-1] += this[i..i+n-1] * x + c. | 810 // w[j..j+n-1] += this[i..i+n-1] * x + c. |
| 763 // Returns carry out. | 811 // Returns carry out. |
| 764 int _amc(int i, int x, _Bigint w, int j, int c, int n) { | 812 int _amc(int i, int x, _Bigint w, int j, int c, int n) { |
| 765 if (x == 0 && c == 0) { | 813 if (x == 0 && c == 0) { |
| 766 // No-op if both x and c are 0. | 814 // No-op if both x and c are 0. |
| 767 return 0; | 815 return 0; |
| 768 } | 816 } |
| 769 int xl = x & DIGIT2_MASK; | 817 int xl = x & DIGIT2_MASK; |
| 770 int xh = x >> DIGIT2_BITS; | 818 int xh = x >> DIGIT2_BITS; |
| 819 var digits = _digits; |
| 820 var w_digits = w._digits; |
| 771 while (--n >= 0) { | 821 while (--n >= 0) { |
| 772 int l = _digits[i] & DIGIT2_MASK; | 822 int l = digits[i] & DIGIT2_MASK; |
| 773 int h = _digits[i++] >> DIGIT2_BITS; | 823 int h = digits[i++] >> DIGIT2_BITS; |
| 774 int m = xh*l + h*xl; | 824 int m = xh*l + h*xl; |
| 775 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + w._digits[j] + c; | 825 l = xl*l + ((m & DIGIT2_MASK) << DIGIT2_BITS) + w_digits[j] + c; |
| 776 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; | 826 c = (l >> DIGIT_BITS) + (m >> DIGIT2_BITS) + xh*h; |
| 777 w._digits[j++] = l & DIGIT_MASK; | 827 w_digits[j++] = l & DIGIT_MASK; |
| 778 } | 828 } |
| 779 return c; | 829 return c; |
| 780 } | 830 } |
| 781 | 831 |
| 782 // r = this * a. | 832 // r = this * a. |
| 783 void _mulTo(_Bigint a, _Bigint r) { | 833 void _mulTo(_Bigint a, _Bigint r) { |
| 784 // TODO(regis): Use karatsuba multiplication when appropriate. | 834 // TODO(regis): Use karatsuba multiplication when appropriate. |
| 785 var i = _used; | 835 var used = _used; |
| 786 r._ensureLength(i + a._used); | 836 var a_used = a._used; |
| 787 r._used = i + a._used; | 837 var i = used; |
| 838 r._ensureLength(i + a_used); |
| 839 var a_digits = a._digits; |
| 840 var r_digits = r._digits; |
| 841 r._used = i + a_used; |
| 788 while (--i >= 0) { | 842 while (--i >= 0) { |
| 789 r._digits[i] = 0; | 843 r_digits[i] = 0; |
| 790 } | 844 } |
| 791 for (i = 0; i < a._used; ++i) { | 845 for (i = 0; i < a_used; ++i) { |
| 792 r._digits[i + _used] = _am(0, a._digits[i], r, i, _used); | 846 r_digits[i + used] = _am(0, a_digits[i], r, i, used); |
| 793 } | 847 } |
| 794 r._clamp(); | 848 r._clamp(); |
| 795 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. | 849 r._neg = r._used > 0 && _neg != a._neg; // Zero cannot be negative. |
| 796 } | 850 } |
| 797 | 851 |
| 798 // r = this^2, r != this. | 852 // r = this^2, r != this. |
| 799 void _sqrTo(_Bigint r) { | 853 void _sqrTo(_Bigint r) { |
| 800 var i = 2 * _used; | 854 var used = _used; |
| 801 r._ensureLength(i); | 855 var r_used = 2 * used; |
| 802 r._used = i; | 856 r._ensureLength(r_used); |
| 857 var digits = _digits; |
| 858 var r_digits = r._digits; |
| 859 var i = r_used; |
| 803 while (--i >= 0) { | 860 while (--i >= 0) { |
| 804 r._digits[i] = 0; | 861 r_digits[i] = 0; |
| 805 } | 862 } |
| 806 for (i = 0; i < _used - 1; ++i) { | 863 for (i = 0; i < used - 1; ++i) { |
| 807 var c = _am(i, _digits[i], r, 2*i, 1); | 864 var c = _am(i, digits[i], r, 2*i, 1); |
| 808 var d = r._digits[i + _used]; | 865 var d = r_digits[i + used]; |
| 809 d += _amc(i + 1, _digits[i] << 1, r, 2*i + 1, c, _used - i - 1); | 866 d += _amc(i + 1, digits[i] << 1, r, 2*i + 1, c, used - i - 1); |
| 810 if (d >= DIGIT_BASE) { | 867 if (d >= DIGIT_BASE) { |
| 811 r._digits[i + _used] = d - DIGIT_BASE; | 868 r_digits[i + used] = d - DIGIT_BASE; |
| 812 r._digits[i + _used + 1] = 1; | 869 r_digits[i + used + 1] = 1; |
| 813 } else { | 870 } else { |
| 814 r._digits[i + _used] = d; | 871 r_digits[i + used] = d; |
| 815 } | 872 } |
| 816 } | 873 } |
| 817 if (r._used > 0) { | 874 if (r_used > 0) { |
| 818 r._digits[r._used - 1] += _am(i, _digits[i], r, 2*i, 1); | 875 r_digits[r_used - 1] += _am(i, digits[i], r, 2*i, 1); |
| 819 } | 876 } |
| 877 r._used = r_used; |
| 820 r._neg = false; | 878 r._neg = false; |
| 821 r._clamp(); | 879 r._clamp(); |
| 822 } | 880 } |
| 823 | 881 |
| 824 // Truncating division and remainder. | 882 // Truncating division and remainder. |
| 825 // If q != null, q = trunc(this / a). | 883 // If q != null, q = trunc(this / a). |
| 826 // If r != null, r = this - a * trunc(this / a). | 884 // If r != null, r = this - a * trunc(this / a). |
| 827 void _divRemTo(_Bigint a, _Bigint q, _Bigint r) { | 885 void _divRemTo(_Bigint a, _Bigint q, _Bigint r) { |
| 828 if (a._used == 0) return; | 886 if (a._used == 0) return; |
| 829 if (_used < a._used) { | 887 if (_used < a._used) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 847 _lShiftTo(nsh, r); | 905 _lShiftTo(nsh, r); |
| 848 } | 906 } |
| 849 else { | 907 else { |
| 850 a._copyTo(y); | 908 a._copyTo(y); |
| 851 _copyTo(r); | 909 _copyTo(r); |
| 852 } | 910 } |
| 853 // We consider this and a positive. Ignore the copied sign. | 911 // We consider this and a positive. Ignore the copied sign. |
| 854 y._neg = false; | 912 y._neg = false; |
| 855 r._neg = false; | 913 r._neg = false; |
| 856 var y_used = y._used; | 914 var y_used = y._used; |
| 857 var y0 = y._digits[y_used - 1]; | 915 var y_digits = y._digits; |
| 916 var y0 = y_digits[y_used - 1]; |
| 858 if (y0 == 0) return; | 917 if (y0 == 0) return; |
| 859 var yt = y0 >> 1; // Chop off one bit, see below. y is normalized: yt != 0. | 918 var yt = y0 >> 1; // Chop off one bit, see below. y is normalized: yt != 0. |
| 860 var i = r._used; | 919 var i = r._used; |
| 861 var j = i - y_used; | 920 var j = i - y_used; |
| 862 _Bigint t = (q == null) ? new _Bigint() : q; | 921 _Bigint t = (q == null) ? new _Bigint() : q; |
| 863 | |
| 864 y._dlShiftTo(j, t); | 922 y._dlShiftTo(j, t); |
| 865 | 923 var r_digits = r._digits; |
| 866 if (r._compareTo(t) >= 0) { | 924 if (r._compareTo(t) >= 0) { |
| 867 r._digits[r._used++] = 1; | 925 r_digits[r._used++] = 1; |
| 868 r._subTo(t, r); | 926 r._subTo(t, r); |
| 869 } | 927 } |
| 870 ONE._dlShiftTo(y_used, t); | 928 ONE._dlShiftTo(y_used, t); |
| 871 t._subTo(y, y); // Negate y so we can replace sub with _am later. | 929 t._subTo(y, y); // Negate y so we can replace sub with _am later. |
| 872 while (y._used < y_used) { | 930 while (y._used < y_used) { |
| 873 y._digits[y._used++] = 0; | 931 y_digits[y._used++] = 0; |
| 874 } | 932 } |
| 875 while (--j >= 0) { | 933 while (--j >= 0) { |
| 876 // Estimate quotient digit. | 934 // Estimate quotient digit. |
| 935 // TODO(regis): Move the expensive mint division below to a function that |
| 936 // can be intrinsified using an uint64_t by uint32_t division instruction, |
| 937 // e.g. qd = _estqd(r_digits, --i, y0). |
| 877 var qd; | 938 var qd; |
| 878 if (r._digits[--i] == y0) { | 939 if (r_digits[--i] == y0) { |
| 879 qd = DIGIT_MASK; | 940 qd = DIGIT_MASK; |
| 880 } else { | 941 } else { |
| 881 // Chop off one bit, since a Mint cannot hold 2 DIGITs. | 942 // Chop off one bit, since a Mint cannot hold 2 DIGITs. |
| 882 qd = ((r._digits[i] << (DIGIT_BITS - 1)) | | 943 qd = ((r_digits[i] << (DIGIT_BITS - 1)) | (r_digits[i - 1] >> 1)) ~/ yt; |
| 883 (r._digits[i - 1] >> 1)) ~/ yt; | |
| 884 } | 944 } |
| 885 if ((r._digits[i] += y._am(0, qd, r, j, y_used)) < qd) { // Try it out. | 945 if ((r_digits[i] += y._am(0, qd, r, j, y_used)) < qd) { // Try it out. |
| 886 y._dlShiftTo(j, t); | 946 y._dlShiftTo(j, t); |
| 887 r._subTo(t, r); | 947 r._subTo(t, r); |
| 888 while (r._digits[i] < --qd) { | 948 while (r_digits[i] < --qd) { |
| 889 r._subTo(t, r); | 949 r._subTo(t, r); |
| 890 } | 950 } |
| 891 } | 951 } |
| 892 } | 952 } |
| 893 if (q != null) { | 953 if (q != null) { |
| 894 r._drShiftTo(y_used, q); | 954 r._drShiftTo(y_used, q); |
| 895 if (_neg != a._neg) { | 955 if (_neg != a._neg) { |
| 896 ZERO._subTo(q, q); | 956 ZERO._subTo(q, q); |
| 897 } | 957 } |
| 898 } | 958 } |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1161 z._mulTo(g2, g[n - 2], g[n]); | 1221 z._mulTo(g2, g[n - 2], g[n]); |
| 1162 n += 2; | 1222 n += 2; |
| 1163 } | 1223 } |
| 1164 } | 1224 } |
| 1165 var j = e._used - 1; | 1225 var j = e._used - 1; |
| 1166 var w; | 1226 var w; |
| 1167 var is1 = true; | 1227 var is1 = true; |
| 1168 var r = new _Bigint()._setInt(1); | 1228 var r = new _Bigint()._setInt(1); |
| 1169 var r2 = new _Bigint(); | 1229 var r2 = new _Bigint(); |
| 1170 var t; | 1230 var t; |
| 1171 i = _nbits(e._digits[j]) - 1; | 1231 var e_digits = e._digits; |
| 1232 i = _nbits(e_digits[j]) - 1; |
| 1172 while (j >= 0) { | 1233 while (j >= 0) { |
| 1173 if (i >= k1) { | 1234 if (i >= k1) { |
| 1174 w = (e._digits[j] >> (i - k1)) & km; | 1235 w = (e_digits[j] >> (i - k1)) & km; |
| 1175 } else { | 1236 } else { |
| 1176 w = (e._digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i); | 1237 w = (e_digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i); |
| 1177 if (j > 0) { | 1238 if (j > 0) { |
| 1178 w |= e._digits[j - 1] >> (DIGIT_BITS + i - k1); | 1239 w |= e_digits[j - 1] >> (DIGIT_BITS + i - k1); |
| 1179 } | 1240 } |
| 1180 } | 1241 } |
| 1181 n = k; | 1242 n = k; |
| 1182 while ((w & 1) == 0) { | 1243 while ((w & 1) == 0) { |
| 1183 w >>= 1; | 1244 w >>= 1; |
| 1184 --n; | 1245 --n; |
| 1185 } | 1246 } |
| 1186 if ((i -= n) < 0) { | 1247 if ((i -= n) < 0) { |
| 1187 i += DIGIT_BITS; | 1248 i += DIGIT_BITS; |
| 1188 --j; | 1249 --j; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1200 if (n > 0) { | 1261 if (n > 0) { |
| 1201 z._sqrTo(r, r2); | 1262 z._sqrTo(r, r2); |
| 1202 } else { | 1263 } else { |
| 1203 t = r; | 1264 t = r; |
| 1204 r = r2; | 1265 r = r2; |
| 1205 r2 = t; | 1266 r2 = t; |
| 1206 } | 1267 } |
| 1207 z._mulTo(r2,g[w], r); | 1268 z._mulTo(r2,g[w], r); |
| 1208 } | 1269 } |
| 1209 | 1270 |
| 1210 while (j >= 0 && (e._digits[j] & (1 << i)) == 0) { | 1271 while (j >= 0 && (e_digits[j] & (1 << i)) == 0) { |
| 1211 z._sqrTo(r, r2); | 1272 z._sqrTo(r, r2); |
| 1212 t = r; | 1273 t = r; |
| 1213 r = r2; | 1274 r = r2; |
| 1214 r2 = t; | 1275 r2 = t; |
| 1215 if (--i < 0) { | 1276 if (--i < 0) { |
| 1216 i = DIGIT_BITS - 1; | 1277 i = DIGIT_BITS - 1; |
| 1217 --j; | 1278 --j; |
| 1218 } | 1279 } |
| 1219 } | 1280 } |
| 1220 } | 1281 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1263 _Bigint _revert(_Bigint x) { | 1324 _Bigint _revert(_Bigint x) { |
| 1264 var r = new _Bigint(); | 1325 var r = new _Bigint(); |
| 1265 x._copyTo(r); | 1326 x._copyTo(r); |
| 1266 _reduce(r); | 1327 _reduce(r); |
| 1267 return r; | 1328 return r; |
| 1268 } | 1329 } |
| 1269 | 1330 |
| 1270 // x = x/R mod _m | 1331 // x = x/R mod _m |
| 1271 void _reduce(_Bigint x) { | 1332 void _reduce(_Bigint x) { |
| 1272 x._ensureLength(_mused2 + 1); | 1333 x._ensureLength(_mused2 + 1); |
| 1334 var x_digits = x._digits; |
| 1273 while (x._used <= _mused2) { // Pad x so _am has enough room later. | 1335 while (x._used <= _mused2) { // Pad x so _am has enough room later. |
| 1274 x._digits[x._used++] = 0; | 1336 x_digits[x._used++] = 0; |
| 1275 } | 1337 } |
| 1276 for (var i = 0; i < _m._used; ++i) { | 1338 var m_used = _m._used; |
| 1339 for (var i = 0; i < m_used; ++i) { |
| 1277 // Faster way of calculating u0 = x[i]*mp mod DIGIT_BASE. | 1340 // Faster way of calculating u0 = x[i]*mp mod DIGIT_BASE. |
| 1278 var j = x._digits[i] & _Bigint.DIGIT2_MASK; | 1341 var j = x_digits[i] & _Bigint.DIGIT2_MASK; |
| 1279 var u0 = (j*_mpl + (((j*_mph + (x._digits[i] >> _Bigint.DIGIT2_BITS) | 1342 var u0 = (j*_mpl + (((j*_mph + (x_digits[i] >> _Bigint.DIGIT2_BITS) |
| 1280 *_mpl) & _um) << _Bigint.DIGIT2_BITS)) & _Bigint.DIGIT_MASK; | 1343 *_mpl) & _um) << _Bigint.DIGIT2_BITS)) & _Bigint.DIGIT_MASK; |
| 1281 // Use _am to combine the multiply-shift-add into one call. | 1344 // Use _am to combine the multiply-shift-add into one call. |
| 1282 j = i + _m._used; | 1345 j = i + m_used; |
| 1283 var digit = x._digits[j]; | 1346 var digit = x_digits[j]; |
| 1284 digit += _m ._am(0, u0, x, i, _m._used); | 1347 digit += _m ._am(0, u0, x, i, m_used); |
| 1285 // Propagate carry. | 1348 // Propagate carry. |
| 1286 while (digit >= _Bigint.DIGIT_BASE) { | 1349 while (digit >= _Bigint.DIGIT_BASE) { |
| 1287 digit -= _Bigint.DIGIT_BASE; | 1350 digit -= _Bigint.DIGIT_BASE; |
| 1288 x._digits[j++] = digit; | 1351 x_digits[j++] = digit; |
| 1289 digit = x._digits[j]; | 1352 digit = x_digits[j]; |
| 1290 digit++; | 1353 digit++; |
| 1291 } | 1354 } |
| 1292 x._digits[j] = digit; | 1355 x_digits[j] = digit; |
| 1293 } | 1356 } |
| 1294 x._clamp(); | 1357 x._clamp(); |
| 1295 x._drShiftTo(_m ._used, x); | 1358 x._drShiftTo(m_used, x); |
| 1296 if (x._compareTo(_m ) >= 0) { | 1359 if (x._compareTo(_m) >= 0) { |
| 1297 x._subTo(_m , x); | 1360 x._subTo(_m, x); |
| 1298 } | 1361 } |
| 1299 } | 1362 } |
| 1300 | 1363 |
| 1301 // r = x^2/R mod _m ; x != r | 1364 // r = x^2/R mod _m ; x != r |
| 1302 void _sqrTo(_Bigint x, _Bigint r) { | 1365 void _sqrTo(_Bigint x, _Bigint r) { |
| 1303 x._sqrTo(r); | 1366 x._sqrTo(r); |
| 1304 _reduce(r); | 1367 _reduce(r); |
| 1305 } | 1368 } |
| 1306 | 1369 |
| 1307 // r = x*y/R mod _m ; x, y != r | 1370 // r = x*y/R mod _m ; x, y != r |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1342 void _sqrTo(_Bigint x, _Bigint r) { | 1405 void _sqrTo(_Bigint x, _Bigint r) { |
| 1343 x._sqrTo(r); | 1406 x._sqrTo(r); |
| 1344 _reduce(r); | 1407 _reduce(r); |
| 1345 } | 1408 } |
| 1346 | 1409 |
| 1347 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { | 1410 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { |
| 1348 x._mulTo(y, r); | 1411 x._mulTo(y, r); |
| 1349 _reduce(r); | 1412 _reduce(r); |
| 1350 } | 1413 } |
| 1351 } | 1414 } |
| OLD | NEW |