OLD | NEW |
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 extends _Num { | 7 class _IntegerImplementation extends _Num { |
8 factory _IntegerImplementation._uninstantiable() { | 8 // The Dart class _Bigint extending _IntegerImplementation requires a |
9 throw new UnsupportedError( | 9 // default constructor. |
10 "_IntegerImplementation can only be allocated by the VM"); | |
11 } | |
12 | 10 |
13 Type get runtimeType => int; | 11 Type get runtimeType => int; |
14 | 12 |
15 num operator +(num other) { | 13 num operator +(num other) { |
16 return other._addFromInteger(this); | 14 var result = other._addFromInteger(this); |
| 15 if (result != null) return result; |
| 16 return other._toBigint()._addFromInteger(this); |
17 } | 17 } |
18 num operator -(num other) { | 18 num operator -(num other) { |
19 return other._subFromInteger(this); | 19 var result = other._subFromInteger(this); |
| 20 if (result != null) return result; |
| 21 return other._toBigint()._subFromInteger(this); |
20 } | 22 } |
21 num operator *(num other) { | 23 num operator *(num other) { |
22 return other._mulFromInteger(this); | 24 var result = other._mulFromInteger(this); |
| 25 if (result != null) return result; |
| 26 return other._toBigint()._mulFromInteger(this); |
23 } | 27 } |
24 num operator ~/(num other) { | 28 num operator ~/(num other) { |
25 if ((other is int) && (other == 0)) { | 29 if ((other is int) && (other == 0)) { |
26 throw const IntegerDivisionByZeroException(); | 30 throw const IntegerDivisionByZeroException(); |
27 } | 31 } |
28 return other._truncDivFromInteger(this); | 32 var result = other._truncDivFromInteger(this); |
| 33 if (result != null) return result; |
| 34 return other._toBigint()._truncDivFromInteger(this); |
29 } | 35 } |
30 num operator /(num other) { | 36 num operator /(num other) { |
31 return this.toDouble() / other.toDouble(); | 37 return this.toDouble() / other.toDouble(); |
32 } | 38 } |
33 num operator %(num other) { | 39 num operator %(num other) { |
34 if ((other is int) && (other == 0)) { | 40 if ((other is int) && (other == 0)) { |
35 throw const IntegerDivisionByZeroException(); | 41 throw const IntegerDivisionByZeroException(); |
36 } | 42 } |
37 return other._moduloFromInteger(this); | 43 var result = other._moduloFromInteger(this); |
| 44 if (result != null) return result; |
| 45 return other._toBigint()._moduloFromInteger(this); |
38 } | 46 } |
39 int operator -() { | 47 int operator -() { |
40 return 0 - this; | 48 return 0 - this; |
41 } | 49 } |
42 int operator &(int other) { | 50 int operator &(int other) { |
43 return other._bitAndFromInteger(this); | 51 var result = other._bitAndFromInteger(this); |
| 52 if (result != null) return result; |
| 53 return other._toBigint()._bitAndFromInteger(this); |
44 } | 54 } |
45 int operator |(int other) { | 55 int operator |(int other) { |
46 return other._bitOrFromInteger(this); | 56 var result = other._bitOrFromInteger(this); |
| 57 if (result != null) return result; |
| 58 return other._toBigint()._bitOrFromInteger(this); |
47 } | 59 } |
48 int operator ^(int other) { | 60 int operator ^(int other) { |
49 return other._bitXorFromInteger(this); | 61 var result = other._bitXorFromInteger(this); |
| 62 if (result != null) return result; |
| 63 return other._toBigint()._bitXorFromInteger(this); |
50 } | 64 } |
51 num remainder(num other) { | 65 num remainder(num other) { |
52 return other._remainderFromInteger(this); | 66 return other._remainderFromInteger(this); |
53 } | 67 } |
54 int _bitAndFromInteger(int other) native "Integer_bitAndFromInteger"; | 68 int _bitAndFromInteger(int other) native "Integer_bitAndFromInteger"; |
55 int _bitOrFromInteger(int other) native "Integer_bitOrFromInteger"; | 69 int _bitOrFromInteger(int other) native "Integer_bitOrFromInteger"; |
56 int _bitXorFromInteger(int other) native "Integer_bitXorFromInteger"; | 70 int _bitXorFromInteger(int other) native "Integer_bitXorFromInteger"; |
57 int _addFromInteger(int other) native "Integer_addFromInteger"; | 71 int _addFromInteger(int other) native "Integer_addFromInteger"; |
58 int _subFromInteger(int other) native "Integer_subFromInteger"; | 72 int _subFromInteger(int other) native "Integer_subFromInteger"; |
59 int _mulFromInteger(int other) native "Integer_mulFromInteger"; | 73 int _mulFromInteger(int other) native "Integer_mulFromInteger"; |
60 int _truncDivFromInteger(int other) native "Integer_truncDivFromInteger"; | 74 int _truncDivFromInteger(int other) native "Integer_truncDivFromInteger"; |
61 int _moduloFromInteger(int other) native "Integer_moduloFromInteger"; | 75 int _moduloFromInteger(int other) native "Integer_moduloFromInteger"; |
62 int _remainderFromInteger(int other) { | 76 int _remainderFromInteger(int other) { |
63 return other - (other ~/ this) * this; | 77 return other - (other ~/ this) * this; |
64 } | 78 } |
65 int operator >>(int other) { | 79 int operator >>(int other) { |
66 return other._shrFromInt(this); | 80 var result = other._shrFromInt(this); |
| 81 if (result != null) return result; |
| 82 return other._toBigint()._shrFromInt(this); |
67 } | 83 } |
68 int operator <<(int other) { | 84 int operator <<(int other) { |
69 return other._shlFromInt(this); | 85 var result = other._shlFromInt(this); |
| 86 if (result != null) return result; |
| 87 return other._toBigint()._shlFromInt(this); |
70 } | 88 } |
71 bool operator <(num other) { | 89 bool operator <(num other) { |
72 return other > this; | 90 return other > this; |
73 } | 91 } |
74 bool operator >(num other) { | 92 bool operator >(num other) { |
75 return other._greaterThanFromInteger(this); | 93 return other._greaterThanFromInteger(this); |
76 } | 94 } |
77 bool operator >=(num other) { | 95 bool operator >=(num other) { |
78 return (this == other) || (this > other); | 96 return (this == other) || (this > other); |
79 } | 97 } |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 } | 193 } |
176 if (lowerLimit.isNaN) return lowerLimit; | 194 if (lowerLimit.isNaN) return lowerLimit; |
177 // Note that we don't need to care for -0.0 for the lower limit. | 195 // Note that we don't need to care for -0.0 for the lower limit. |
178 if (this < lowerLimit) return lowerLimit; | 196 if (this < lowerLimit) return lowerLimit; |
179 if (this.compareTo(upperLimit) > 0) return upperLimit; | 197 if (this.compareTo(upperLimit) > 0) return upperLimit; |
180 return this; | 198 return this; |
181 } | 199 } |
182 | 200 |
183 int toInt() { return this; } | 201 int toInt() { return this; } |
184 double toDouble() { return new _Double.fromInteger(this); } | 202 double toDouble() { return new _Double.fromInteger(this); } |
| 203 _Bigint _toBigint() { return new _Bigint()._setInt(this); } |
185 | 204 |
186 String toStringAsFixed(int fractionDigits) { | 205 String toStringAsFixed(int fractionDigits) { |
187 return this.toDouble().toStringAsFixed(fractionDigits); | 206 return this.toDouble().toStringAsFixed(fractionDigits); |
188 } | 207 } |
189 String toStringAsExponential([int fractionDigits]) { | 208 String toStringAsExponential([int fractionDigits]) { |
190 return this.toDouble().toStringAsExponential(fractionDigits); | 209 return this.toDouble().toStringAsExponential(fractionDigits); |
191 } | 210 } |
192 String toStringAsPrecision(int precision) { | 211 String toStringAsPrecision(int precision) { |
193 return this.toDouble().toStringAsPrecision(precision); | 212 return this.toDouble().toStringAsPrecision(precision); |
194 } | 213 } |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 // Shift by mint exceeds range that can be handled by the VM. | 476 // Shift by mint exceeds range that can be handled by the VM. |
458 int _shrFromInt(int other) { | 477 int _shrFromInt(int other) { |
459 if (other < 0) { | 478 if (other < 0) { |
460 return -1; | 479 return -1; |
461 } else { | 480 } else { |
462 return 0; | 481 return 0; |
463 } | 482 } |
464 } | 483 } |
465 int _shlFromInt(int other) native "Mint_shlFromInt"; | 484 int _shlFromInt(int other) native "Mint_shlFromInt"; |
466 } | 485 } |
467 | |
468 // A number that can be represented as Smi or Mint will never be represented as | |
469 // Bigint. | |
470 class _Bigint extends _IntegerImplementation implements int { | |
471 factory _Bigint._uninstantiable() { | |
472 throw new UnsupportedError( | |
473 "_Bigint can only be allocated by the VM"); | |
474 } | |
475 int get _identityHashCode { | |
476 return this; | |
477 } | |
478 int operator ~() native "Bigint_bitNegate"; | |
479 int get bitLength native "Bigint_bitLength"; | |
480 | |
481 // Shift by bigint exceeds range that can be handled by the VM. | |
482 int _shrFromInt(int other) { | |
483 if (other < 0) { | |
484 return -1; | |
485 } else { | |
486 return 0; | |
487 } | |
488 } | |
489 int _shlFromInt(int other) native "Bigint_shlFromInt"; | |
490 | |
491 int pow(int exponent) { | |
492 throw "Bigint.pow not implemented"; | |
493 } | |
494 } | |
OLD | NEW |