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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 if ((t = x >> 16) != 0) { x = t; r += 16; } | 164 if ((t = x >> 16) != 0) { x = t; r += 16; } |
| 165 if ((t = x >> 8) != 0) { x = t; r += 8; } | 165 if ((t = x >> 8) != 0) { x = t; r += 8; } |
| 166 if ((t = x >> 4) != 0) { x = t; r += 4; } | 166 if ((t = x >> 4) != 0) { x = t; r += 4; } |
| 167 if ((t = x >> 2) != 0) { x = t; r += 2; } | 167 if ((t = x >> 2) != 0) { x = t; r += 2; } |
| 168 if ((x >> 1) != 0) { r += 1; } | 168 if ((x >> 1) != 0) { r += 1; } |
| 169 return r; | 169 return r; |
| 170 } | 170 } |
| 171 | 171 |
| 172 // Return this << n*_DIGIT_BITS. | 172 // Return this << n*_DIGIT_BITS. |
| 173 _Bigint _dlShift(int n) { | 173 _Bigint _dlShift(int n) { |
| 174 var used = _used; | 174 final used = _used; |
| 175 if (used == 0) { | 175 if (used == 0) { |
| 176 return _ZERO; | 176 return _ZERO; |
| 177 } | 177 } |
| 178 var r_used = used + n; | 178 final r_used = used + n; |
| 179 var digits = _digits; | 179 final digits = _digits; |
| 180 var r_digits = new Uint32List(r_used + (r_used & 1)); | 180 final r_digits = new Uint32List(r_used + (r_used & 1)); |
| 181 var i = used; | 181 var i = used; |
| 182 while (--i >= 0) { | 182 while (--i >= 0) { |
| 183 r_digits[i + n] = digits[i]; | 183 r_digits[i + n] = digits[i]; |
| 184 } | 184 } |
| 185 return new _Bigint(_neg, r_used, r_digits); | 185 return new _Bigint(_neg, r_used, r_digits); |
| 186 } | 186 } |
| 187 | 187 |
| 188 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n*_DIGIT_BITS. | 188 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n*_DIGIT_BITS. |
| 189 // Return r_used. | 189 // Return r_used. |
| 190 static int _dlShiftDigits(Uint32List x_digits, int x_used, int n, | 190 static int _dlShiftDigits(Uint32List x_digits, int x_used, int n, |
| 191 Uint32List r_digits) { | 191 Uint32List r_digits) { |
| 192 if (x_used == 0) { | 192 if (x_used == 0) { |
| 193 return 0; | 193 return 0; |
| 194 } | 194 } |
| 195 if (n == 0 && r_digits == x_digits) { | 195 if (n == 0 && r_digits == x_digits) { |
| 196 return x_used; | 196 return x_used; |
| 197 } | 197 } |
| 198 var r_used = x_used + n; | 198 final r_used = x_used + n; |
| 199 assert(r_digits.length >= r_used + (r_used & 1)); | 199 assert(r_digits.length >= r_used + (r_used & 1)); |
| 200 var i = x_used; | 200 var i = x_used; |
| 201 while (--i >= 0) { | 201 while (--i >= 0) { |
| 202 r_digits[i + n] = x_digits[i]; | 202 r_digits[i + n] = x_digits[i]; |
| 203 } | 203 } |
| 204 i = n; | 204 i = n; |
| 205 while (--i >= 0) { | 205 while (--i >= 0) { |
| 206 r_digits[i] = 0; | 206 r_digits[i] = 0; |
| 207 } | 207 } |
| 208 if (r_used.isOdd) { | 208 if (r_used.isOdd) { |
| 209 r_digits[r_used] = 0; | 209 r_digits[r_used] = 0; |
| 210 } | 210 } |
| 211 return r_used; | 211 return r_used; |
| 212 } | 212 } |
| 213 | 213 |
| 214 // Return this >> n*_DIGIT_BITS. | 214 // Return this >> n*_DIGIT_BITS. |
| 215 _Bigint _drShift(int n) { | 215 _Bigint _drShift(int n) { |
| 216 var used = _used; | 216 final used = _used; |
| 217 if (used == 0) { | 217 if (used == 0) { |
| 218 return _ZERO; | 218 return _ZERO; |
| 219 } | 219 } |
| 220 var r_used = used - n; | 220 final r_used = used - n; |
| 221 if (r_used <= 0) { | 221 if (r_used <= 0) { |
| 222 return _neg ? _MINUS_ONE : _ZERO; | 222 return _neg ? _MINUS_ONE : _ZERO; |
| 223 } | 223 } |
| 224 var digits = _digits; | 224 final digits = _digits; |
| 225 var r_digits = new Uint32List(r_used + (r_used & 1)); | 225 final r_digits = new Uint32List(r_used + (r_used & 1)); |
| 226 for (var i = n; i < used; i++) { | 226 for (var i = n; i < used; i++) { |
| 227 r_digits[i - n] = digits[i]; | 227 r_digits[i - n] = digits[i]; |
| 228 } | 228 } |
| 229 var r = new _Bigint(_neg, r_used, r_digits); | 229 final r = new _Bigint(_neg, r_used, r_digits); |
| 230 if (_neg) { | 230 if (_neg) { |
| 231 // Round down if any bit was shifted out. | 231 // Round down if any bit was shifted out. |
| 232 for (var i = 0; i < n; i++) { | 232 for (var i = 0; i < n; i++) { |
| 233 if (digits[i] != 0) { | 233 if (digits[i] != 0) { |
| 234 return r._sub(_ONE); | 234 return r._sub(_ONE); |
| 235 } | 235 } |
| 236 } | 236 } |
| 237 } | 237 } |
| 238 return r; | 238 return r; |
| 239 } | 239 } |
| 240 | 240 |
| 241 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n*_DIGIT_BITS. | 241 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n*_DIGIT_BITS. |
| 242 // Return r_used. | 242 // Return r_used. |
| 243 static int _drShiftDigits(Uint32List x_digits, int x_used, int n, | 243 static int _drShiftDigits(Uint32List x_digits, int x_used, int n, |
| 244 Uint32List r_digits) { | 244 Uint32List r_digits) { |
| 245 var r_used = x_used - n; | 245 final r_used = x_used - n; |
| 246 if (r_used <= 0) { | 246 if (r_used <= 0) { |
| 247 return 0; | 247 return 0; |
| 248 } | 248 } |
| 249 assert(r_digits.length >= r_used + (r_used & 1)); | 249 assert(r_digits.length >= r_used + (r_used & 1)); |
| 250 for (var i = n; i < x_used; i++) { | 250 for (var i = n; i < x_used; i++) { |
| 251 r_digits[i - n] = x_digits[i]; | 251 r_digits[i - n] = x_digits[i]; |
| 252 } | 252 } |
| 253 if (r_used.isOdd) { | 253 if (r_used.isOdd) { |
| 254 r_digits[r_used] = 0; | 254 r_digits[r_used] = 0; |
| 255 } | 255 } |
| 256 return r_used; | 256 return r_used; |
| 257 } | 257 } |
| 258 | 258 |
| 259 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. | |
| 260 static void _lsh(Uint32List x_digits, int x_used, int n, | |
| 261 Uint32List r_digits) { | |
| 262 final ds = n ~/ _DIGIT_BITS; | |
| 263 final bs = n % _DIGIT_BITS; | |
|
srdjan
2015/03/27 22:29:54
You compute now ds and bs twice: once here and onc
regis
2015/03/27 22:41:46
Correct. It is cheaper to recalculate the values f
| |
| 264 final cbs = _DIGIT_BITS - bs; | |
| 265 final bm = (1 << cbs) - 1; | |
| 266 var c = 0; | |
| 267 var i = x_used; | |
| 268 while (--i >= 0) { | |
| 269 final d = x_digits[i]; | |
| 270 r_digits[i + ds + 1] = (d >> cbs) | c; | |
| 271 c = (d & bm) << bs; | |
| 272 } | |
| 273 r_digits[ds] = c; | |
| 274 i = ds; | |
| 275 while (--i >= 0) { | |
| 276 r_digits[i] = 0; | |
| 277 } | |
| 278 } | |
| 279 | |
| 259 // Return this << n. | 280 // Return this << n. |
| 260 _Bigint _lShift(int n) { | 281 _Bigint _lShift(int n) { |
| 261 var ds = n ~/ _DIGIT_BITS; | 282 final ds = n ~/ _DIGIT_BITS; |
| 262 var bs = n % _DIGIT_BITS; | 283 final bs = n % _DIGIT_BITS; |
| 263 if (bs == 0) { | 284 if (bs == 0) { |
| 264 return _dlShift(ds); | 285 return _dlShift(ds); |
| 265 } | 286 } |
| 266 var cbs = _DIGIT_BITS - bs; | |
| 267 var bm = (1 << cbs) - 1; | |
| 268 var r_used = _used + ds + 1; | 287 var r_used = _used + ds + 1; |
| 269 var digits = _digits; | |
| 270 var r_digits = new Uint32List(r_used + (r_used & 1)); | 288 var r_digits = new Uint32List(r_used + (r_used & 1)); |
| 271 var c = 0; | 289 _lsh(_digits, _used, n, r_digits); |
| 272 var i = _used; | |
| 273 while (--i >= 0) { | |
| 274 final d = digits[i]; | |
| 275 r_digits[i + ds + 1] = (d >> cbs) | c; | |
| 276 c = (d & bm) << bs; | |
| 277 } | |
| 278 r_digits[ds] = c; | |
| 279 return new _Bigint(_neg, r_used, r_digits); | 290 return new _Bigint(_neg, r_used, r_digits); |
| 280 } | 291 } |
| 281 | 292 |
| 282 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. | 293 // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n. |
| 283 // Return r_used. | 294 // Return r_used. |
| 284 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, | 295 static int _lShiftDigits(Uint32List x_digits, int x_used, int n, |
| 285 Uint32List r_digits) { | 296 Uint32List r_digits) { |
| 286 var ds = n ~/ _DIGIT_BITS; | 297 final ds = n ~/ _DIGIT_BITS; |
| 287 var bs = n % _DIGIT_BITS; | 298 final bs = n % _DIGIT_BITS; |
| 288 if (bs == 0) { | 299 if (bs == 0) { |
| 289 return _dlShiftDigits(x_digits, x_used, ds, r_digits); | 300 return _dlShiftDigits(x_digits, x_used, ds, r_digits); |
| 290 } | 301 } |
| 291 var cbs = _DIGIT_BITS - bs; | |
| 292 var bm = (1 << cbs) - 1; | |
| 293 var r_used = x_used + ds + 1; | 302 var r_used = x_used + ds + 1; |
| 294 assert(r_digits.length >= r_used + (r_used & 1)); | 303 assert(r_digits.length >= r_used + (r_used & 1)); |
| 295 var c = 0; | 304 _lsh(x_digits, x_used, n, r_digits); |
| 296 var i = x_used; | |
| 297 while (--i >= 0) { | |
| 298 final d = x_digits[i]; | |
| 299 r_digits[i + ds + 1] = (d >> cbs) | c; | |
| 300 c = (d & bm) << bs; | |
| 301 } | |
| 302 r_digits[ds] = c; | |
| 303 i = ds; | |
| 304 while (--i >= 0) { | |
| 305 r_digits[i] = 0; | |
| 306 } | |
| 307 if (r_digits[r_used - 1] == 0) { | 305 if (r_digits[r_used - 1] == 0) { |
| 308 r_used--; // Clamp result. | 306 r_used--; // Clamp result. |
| 309 } else if (r_used.isOdd) { | 307 } else if (r_used.isOdd) { |
| 310 r_digits[r_used] = 0; | 308 r_digits[r_used] = 0; |
| 311 } | 309 } |
| 312 return r_used; | 310 return r_used; |
| 313 } | 311 } |
| 314 | 312 |
| 313 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n. | |
| 314 static void _rsh(Uint32List x_digits, int x_used, int n, | |
| 315 Uint32List r_digits) { | |
| 316 final ds = n ~/ _DIGIT_BITS; | |
| 317 final bs = n % _DIGIT_BITS; | |
| 318 final cbs = _DIGIT_BITS - bs; | |
| 319 final bm = (1 << bs) - 1; | |
| 320 var c = x_digits[ds] >> bs; | |
| 321 final last = x_used - ds - 1; | |
| 322 for (var i = 0; i < last; i++) { | |
| 323 final d = x_digits[i + ds + 1]; | |
| 324 r_digits[i] = ((d & bm) << cbs) | c; | |
| 325 c = d >> bs; | |
| 326 } | |
| 327 r_digits[last] = c; | |
| 328 } | |
| 329 | |
| 315 // Return this >> n. | 330 // Return this >> n. |
| 316 _Bigint _rShift(int n) { | 331 _Bigint _rShift(int n) { |
| 317 var ds = n ~/ _DIGIT_BITS; | 332 final ds = n ~/ _DIGIT_BITS; |
| 318 var bs = n % _DIGIT_BITS; | 333 final bs = n % _DIGIT_BITS; |
| 319 if (bs == 0) { | 334 if (bs == 0) { |
| 320 return _drShift(ds); | 335 return _drShift(ds); |
| 321 } | 336 } |
| 322 var r_used = _used - ds; | 337 final used = _used; |
| 338 final r_used = used - ds; | |
| 323 if (r_used <= 0) { | 339 if (r_used <= 0) { |
| 324 return _neg ? _MINUS_ONE : _ZERO; | 340 return _neg ? _MINUS_ONE : _ZERO; |
| 325 } | 341 } |
| 326 var cbs = _DIGIT_BITS - bs; | 342 final digits = _digits; |
| 327 var bm = (1 << bs) - 1; | 343 final r_digits = new Uint32List(r_used + (r_used & 1)); |
| 328 var digits = _digits; | 344 _rsh(digits, used, n, r_digits); |
| 329 var r_digits = new Uint32List(r_used + (r_used & 1)); | 345 final r = new _Bigint(_neg, r_used, r_digits); |
| 330 r_digits[0] = digits[ds] >> bs; | |
| 331 var used = _used; | |
| 332 for (var i = ds + 1; i < used; i++) { | |
| 333 final d = digits[i]; | |
| 334 r_digits[i - ds - 1] |= (d & bm) << cbs; | |
| 335 r_digits[i - ds] = d >> bs; | |
| 336 } | |
| 337 var r = new _Bigint(_neg, r_used, r_digits); | |
| 338 if (_neg) { | 346 if (_neg) { |
| 339 // Round down if any bit was shifted out. | 347 // Round down if any bit was shifted out. |
| 340 if ((digits[ds] & bm) != 0) { | 348 if ((digits[ds] & ((1 << bs) - 1)) != 0) { |
| 341 return r._sub(_ONE); | 349 return r._sub(_ONE); |
| 342 } | 350 } |
| 343 for (var i = 0; i < ds; i++) { | 351 for (var i = 0; i < ds; i++) { |
| 344 if (digits[i] != 0) { | 352 if (digits[i] != 0) { |
| 345 return r._sub(_ONE); | 353 return r._sub(_ONE); |
| 346 } | 354 } |
| 347 } | 355 } |
| 348 } | 356 } |
| 349 return r; | 357 return r; |
| 350 } | 358 } |
| 351 | 359 |
| 352 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n. | 360 // r_digits[0..r_used-1] = x_digits[0..x_used-1] >> n. |
| 353 // Return r_used. | 361 // Return r_used. |
| 354 static int _rShiftDigits(Uint32List x_digits, int x_used, int n, | 362 static int _rShiftDigits(Uint32List x_digits, int x_used, int n, |
| 355 Uint32List r_digits) { | 363 Uint32List r_digits) { |
| 356 var ds = n ~/ _DIGIT_BITS; | 364 final ds = n ~/ _DIGIT_BITS; |
| 357 var bs = n % _DIGIT_BITS; | 365 final bs = n % _DIGIT_BITS; |
| 358 if (bs == 0) { | 366 if (bs == 0) { |
| 359 return _drShiftDigits(x_digits, x_used, ds, r_digits); | 367 return _drShiftDigits(x_digits, x_used, ds, r_digits); |
| 360 } | 368 } |
| 361 var r_used = x_used - ds; | 369 var r_used = x_used - ds; |
| 362 if (r_used <= 0) { | 370 if (r_used <= 0) { |
| 363 return 0; | 371 return 0; |
| 364 } | 372 } |
| 365 var cbs = _DIGIT_BITS - bs; | |
| 366 var bm = (1 << bs) - 1; | |
| 367 assert(r_digits.length >= r_used + (r_used & 1)); | 373 assert(r_digits.length >= r_used + (r_used & 1)); |
| 368 r_digits[0] = x_digits[ds] >> bs; | 374 _rsh(x_digits, x_used, n, r_digits); |
| 369 for (var i = ds + 1; i < x_used; i++) { | |
| 370 final d = x_digits[i]; | |
| 371 r_digits[i - ds - 1] |= (d & bm) << cbs; | |
| 372 r_digits[i - ds] = d >> bs; | |
| 373 } | |
| 374 if (r_digits[r_used - 1] == 0) { | 375 if (r_digits[r_used - 1] == 0) { |
| 375 r_used--; // Clamp result. | 376 r_used--; // Clamp result. |
| 376 } else if (r_used.isOdd) { | 377 } else if (r_used.isOdd) { |
| 377 r_digits[r_used] = 0; | 378 r_digits[r_used] = 0; |
| 378 } | 379 } |
| 379 return r_used; | 380 return r_used; |
| 380 } | 381 } |
| 381 | 382 |
| 382 // Return 0 if abs(this) == abs(a). | 383 // Return 0 if abs(this) == abs(a). |
| 383 // Return a positive number if abs(this) > abs(a). | 384 // Return a positive number if abs(this) > abs(a). |
| (...skipping 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1761 | 1762 |
| 1762 int _mul(Uint32List x_digits, int x_used, | 1763 int _mul(Uint32List x_digits, int x_used, |
| 1763 Uint32List y_digits, int y_used, | 1764 Uint32List y_digits, int y_used, |
| 1764 Uint32List r_digits) { | 1765 Uint32List r_digits) { |
| 1765 var r_used = _Bigint._mulDigits(x_digits, x_used, | 1766 var r_used = _Bigint._mulDigits(x_digits, x_used, |
| 1766 y_digits, y_used, | 1767 y_digits, y_used, |
| 1767 r_digits); | 1768 r_digits); |
| 1768 return _reduce(r_digits, r_used); | 1769 return _reduce(r_digits, r_used); |
| 1769 } | 1770 } |
| 1770 } | 1771 } |
| OLD | NEW |