Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: runtime/lib/integers.dart

Issue 247083002: Avoid comparing smi to mint in smi.toString(). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 // TODO(srdjan): fix limitations. 5 // TODO(srdjan): fix limitations.
6 // - shift amount must be a Smi. 6 // - shift amount must be a Smi.
7 class _IntegerImplementation { 7 class _IntegerImplementation {
8 factory _IntegerImplementation._uninstantiable() { 8 factory _IntegerImplementation._uninstantiable() {
9 throw new UnsupportedError( 9 throw new UnsupportedError(
10 "_IntegerImplementation can only be allocated by the VM"); 10 "_IntegerImplementation can only be allocated by the VM");
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, 287 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31,
288 0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, 288 0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35,
289 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39, 289 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39,
290 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, 290 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33,
291 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, 291 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37,
292 0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31, 292 0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31,
293 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, 293 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35,
294 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39 294 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39
295 ]; 295 ];
296 296
297 // Powers of 10 above 1000000 are indistinguishable. 297 // Powers of 10 above 1000000 are indistinguishable by eye.
298 static const int _POW_10_7 = 10000000; 298 static const int _POW_10_7 = 10000000;
299 static const int _POW_10_8 = 100000000; 299 static const int _POW_10_8 = 100000000;
300 static const int _POW_10_9 = 1000000000; 300 static const int _POW_10_9 = 1000000000;
301 static const int _POW_10_10 = 10000000000;
302 301
303 // Find the number of decimal digits in a positive smi. 302 // Find the number of decimal digits in a positive smi.
304 static int _positiveBase10Length(var smi) { 303 static int _positiveBase10Length(var smi) {
305 // A positive smi has length <= 19 if 63-bit, <=10 if 31-bit. 304 // A positive smi has length <= 19 if 63-bit, <=10 if 31-bit.
306 // Avoid comparing a 31-bit smi to a non-smi. 305 // Avoid comparing a 31-bit smi to a non-smi.
307 if (smi < 1000) return 3; 306 if (smi < 1000) return 3;
308 if (smi < 10000) return 4; 307 if (smi < 10000) return 4;
309 if (smi < _POW_10_7) { 308 if (smi < _POW_10_7) {
310 if (smi < 100000) return 5; 309 if (smi < 100000) return 5;
311 if (smi < 1000000) return 6; 310 if (smi < 1000000) return 6;
312 return 7; 311 return 7;
313 } 312 }
314 if (smi < _POW_10_10) { 313 if (smi < _POW_10_8) return 8;
315 if (smi < _POW_10_8) return 8; 314 if (smi < _POW_10_9) return 9;
316 if (smi < _POW_10_9) return 9; 315 smi = smi ~/ _POW_10_9;
317 return 10; 316 if (smi < 10) return 10;
318 } 317 if (smi < 100) return 11;
Anders Johnsen 2014/04/22 09:21:48 Add comment why we check for 10 and 11 here.
319 smi = smi ~/ _POW_10_10; 318 return 9 + _positiveBase10Length(smi);
320 if (smi < 10) return 11;
321 if (smi < 100) return 12;
322 return 10 + _positiveBase10Length(smi);
323 } 319 }
324 320
325 String toString() { 321 String toString() {
326 if (this < 0) return _negativeToString(this); 322 if (this < 0) return _negativeToString(this);
327 // Inspired by Andrei Alexandrescu: "Three Optimization Tips for C++" 323 // Inspired by Andrei Alexandrescu: "Three Optimization Tips for C++"
328 // Avoid expensive remainder operation by doing it on more than 324 // Avoid expensive remainder operation by doing it on more than
329 // one digit at a time. 325 // one digit at a time.
330 const int DIGIT_ZERO = 0x30; 326 const int DIGIT_ZERO = 0x30;
331 if (this < 10) { 327 if (this < 10) {
332 return _OneByteString._allocate(1).._setAt(0, DIGIT_ZERO + this); 328 return _OneByteString._allocate(1).._setAt(0, DIGIT_ZERO + this);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 static int _negativeBase10Length(var negSmi) { 362 static int _negativeBase10Length(var negSmi) {
367 // A negative smi has length <= 19 if 63-bit, <=10 if 31-bit. 363 // A negative smi has length <= 19 if 63-bit, <=10 if 31-bit.
368 // Avoid comparing a 31-bit smi to a non-smi. 364 // Avoid comparing a 31-bit smi to a non-smi.
369 if (negSmi > -1000) return 3; 365 if (negSmi > -1000) return 3;
370 if (negSmi > -10000) return 4; 366 if (negSmi > -10000) return 4;
371 if (negSmi > -_POW_10_7) { 367 if (negSmi > -_POW_10_7) {
372 if (negSmi > -100000) return 5; 368 if (negSmi > -100000) return 5;
373 if (negSmi > -1000000) return 6; 369 if (negSmi > -1000000) return 6;
374 return 7; 370 return 7;
375 } 371 }
376 if (negSmi > -_POW_10_10) { 372 if (negSmi > -_POW_10_8) return 8;
377 if (negSmi > -_POW_10_8) return 8; 373 if (negSmi > -_POW_10_9) return 9;
378 if (negSmi > -_POW_10_9) return 9; 374 negSmi = negSmi ~/ _POW_10_9;
379 return 10; 375 if (negSmi > -10) return 10;
380 } 376 if (negSmi > -100) return 11;
Anders Johnsen 2014/04/22 09:21:48 Ditto.
381 negSmi = negSmi ~/ _POW_10_10; 377 return 9 + _negativeBase10Length(negSmi);
382 if (negSmi > -10) return 11;
383 if (negSmi > -100) return 12;
384 return 10 + _negativeBase10Length(negSmi);
385 } 378 }
386 379
387 // Convert a negative smi to a string. 380 // Convert a negative smi to a string.
388 // Doesn't negate the smi to avoid negating the most negative smi, which 381 // Doesn't negate the smi to avoid negating the most negative smi, which
389 // would become a non-smi. 382 // would become a non-smi.
390 static String _negativeToString(int negSmi) { 383 static String _negativeToString(int negSmi) {
391 // Character code for '-' 384 // Character code for '-'
392 const int MINUS_SIGN = 0x2d; 385 const int MINUS_SIGN = 0x2d;
393 // Character code for '0'. 386 // Character code for '0'.
394 const int DIGIT_ZERO = 0x30; 387 const int DIGIT_ZERO = 0x30;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 } else { 464 } else {
472 return 0; 465 return 0;
473 } 466 }
474 } 467 }
475 int _shlFromInt(int other) native "Bigint_shlFromInt"; 468 int _shlFromInt(int other) native "Bigint_shlFromInt";
476 469
477 int pow(int exponent) { 470 int pow(int exponent) {
478 throw "Bigint.pow not implemented"; 471 throw "Bigint.pow not implemented";
479 } 472 }
480 } 473 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698