| 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 class _Double implements double { | 5 class _Double implements double { |
| 6 factory _Double.fromInteger(int value) | 6 factory _Double.fromInteger(int value) native "Double_doubleFromInteger"; |
| 7 native "Double_doubleFromInteger"; | |
| 8 | 7 |
| 9 // TODO: Make a stared static method for hashCode and _identityHashCode | 8 // TODO: Make a stared static method for hashCode and _identityHashCode |
| 10 // when semantics are corrected as described in: | 9 // when semantics are corrected as described in: |
| 11 // https://github.com/dart-lang/sdk/issues/2884 | 10 // https://github.com/dart-lang/sdk/issues/2884 |
| 12 int get hashCode => (isNaN || isInfinite) ? 0 : toInt(); | 11 int get hashCode => (isNaN || isInfinite) ? 0 : toInt(); |
| 13 int get _identityHashCode => (isNaN || isInfinite) ? 0 : toInt(); | 12 int get _identityHashCode => (isNaN || isInfinite) ? 0 : toInt(); |
| 14 | 13 |
| 15 double operator +(num other) { | 14 double operator +(num other) { |
| 16 return _add(other.toDouble()); | 15 return _add(other.toDouble()); |
| 17 } | 16 } |
| 17 |
| 18 double _add(double other) native "Double_add"; | 18 double _add(double other) native "Double_add"; |
| 19 | 19 |
| 20 double operator -(num other) { | 20 double operator -(num other) { |
| 21 return _sub(other.toDouble()); | 21 return _sub(other.toDouble()); |
| 22 } | 22 } |
| 23 |
| 23 double _sub(double other) native "Double_sub"; | 24 double _sub(double other) native "Double_sub"; |
| 24 | 25 |
| 25 double operator *(num other) { | 26 double operator *(num other) { |
| 26 return _mul(other.toDouble()); | 27 return _mul(other.toDouble()); |
| 27 } | 28 } |
| 29 |
| 28 double _mul(double other) native "Double_mul"; | 30 double _mul(double other) native "Double_mul"; |
| 29 | 31 |
| 30 int operator ~/(num other) { | 32 int operator ~/(num other) { |
| 31 return _trunc_div(other.toDouble()); | 33 return _trunc_div(other.toDouble()); |
| 32 } | 34 } |
| 35 |
| 33 int _trunc_div(double other) native "Double_trunc_div"; | 36 int _trunc_div(double other) native "Double_trunc_div"; |
| 34 | 37 |
| 35 double operator /(num other) { | 38 double operator /(num other) { |
| 36 return _div(other.toDouble()); | 39 return _div(other.toDouble()); |
| 37 } | 40 } |
| 41 |
| 38 double _div(double other) native "Double_div"; | 42 double _div(double other) native "Double_div"; |
| 39 | 43 |
| 40 double operator %(num other) { | 44 double operator %(num other) { |
| 41 return _modulo(other.toDouble()); | 45 return _modulo(other.toDouble()); |
| 42 } | 46 } |
| 47 |
| 43 double _modulo(double other) native "Double_modulo"; | 48 double _modulo(double other) native "Double_modulo"; |
| 44 | 49 |
| 45 double remainder(num other) { | 50 double remainder(num other) { |
| 46 return _remainder(other.toDouble()); | 51 return _remainder(other.toDouble()); |
| 47 } | 52 } |
| 53 |
| 48 double _remainder(double other) native "Double_remainder"; | 54 double _remainder(double other) native "Double_remainder"; |
| 49 | 55 |
| 50 double operator -() native "Double_flipSignBit"; | 56 double operator -() native "Double_flipSignBit"; |
| 51 | 57 |
| 52 bool operator ==(other) { | 58 bool operator ==(other) { |
| 53 if (!(other is num)) return false; | 59 if (!(other is num)) return false; |
| 54 return _equal(other.toDouble()); | 60 return _equal(other.toDouble()); |
| 55 } | 61 } |
| 62 |
| 56 bool _equal(double other) native "Double_equal"; | 63 bool _equal(double other) native "Double_equal"; |
| 57 bool _equalToInteger(int other) native "Double_equalToInteger"; | 64 bool _equalToInteger(int other) native "Double_equalToInteger"; |
| 58 bool operator <(num other) { | 65 bool operator <(num other) { |
| 59 return other > this; | 66 return other > this; |
| 60 } | 67 } |
| 68 |
| 61 bool operator >(num other) { | 69 bool operator >(num other) { |
| 62 return _greaterThan(other.toDouble()); | 70 return _greaterThan(other.toDouble()); |
| 63 } | 71 } |
| 72 |
| 64 bool _greaterThan(double other) native "Double_greaterThan"; | 73 bool _greaterThan(double other) native "Double_greaterThan"; |
| 65 bool operator >=(num other) { | 74 bool operator >=(num other) { |
| 66 return (this == other) || (this > other); | 75 return (this == other) || (this > other); |
| 67 } | 76 } |
| 77 |
| 68 bool operator <=(num other) { | 78 bool operator <=(num other) { |
| 69 return (this == other) || (this < other); | 79 return (this == other) || (this < other); |
| 70 } | 80 } |
| 81 |
| 71 double _addFromInteger(int other) { | 82 double _addFromInteger(int other) { |
| 72 return new _Double.fromInteger(other)._add(this); | 83 return new _Double.fromInteger(other)._add(this); |
| 73 } | 84 } |
| 85 |
| 74 double _subFromInteger(int other) { | 86 double _subFromInteger(int other) { |
| 75 return new _Double.fromInteger(other)._sub(this); | 87 return new _Double.fromInteger(other)._sub(this); |
| 76 } | 88 } |
| 89 |
| 77 double _mulFromInteger(int other) { | 90 double _mulFromInteger(int other) { |
| 78 return new _Double.fromInteger(other)._mul(this); | 91 return new _Double.fromInteger(other)._mul(this); |
| 79 } | 92 } |
| 93 |
| 80 int _truncDivFromInteger(int other) { | 94 int _truncDivFromInteger(int other) { |
| 81 return new _Double.fromInteger(other)._trunc_div(this); | 95 return new _Double.fromInteger(other)._trunc_div(this); |
| 82 } | 96 } |
| 97 |
| 83 double _moduloFromInteger(int other) { | 98 double _moduloFromInteger(int other) { |
| 84 return new _Double.fromInteger(other)._modulo(this); | 99 return new _Double.fromInteger(other)._modulo(this); |
| 85 } | 100 } |
| 101 |
| 86 double _remainderFromInteger(int other) { | 102 double _remainderFromInteger(int other) { |
| 87 return new _Double.fromInteger(other)._remainder(this); | 103 return new _Double.fromInteger(other)._remainder(this); |
| 88 } | 104 } |
| 105 |
| 89 bool _greaterThanFromInteger(int other) | 106 bool _greaterThanFromInteger(int other) |
| 90 native "Double_greaterThanFromInteger"; | 107 native "Double_greaterThanFromInteger"; |
| 91 | 108 |
| 92 bool get isNegative native "Double_getIsNegative"; | 109 bool get isNegative native "Double_getIsNegative"; |
| 93 bool get isInfinite native "Double_getIsInfinite"; | 110 bool get isInfinite native "Double_getIsInfinite"; |
| 94 bool get isNaN native "Double_getIsNaN"; | 111 bool get isNaN native "Double_getIsNaN"; |
| 95 bool get isFinite => !isInfinite && !isNaN; // Can be optimized. | 112 bool get isFinite => !isInfinite && !isNaN; // Can be optimized. |
| 96 | 113 |
| 97 double abs() { | 114 double abs() { |
| 98 // Handle negative 0.0. | 115 // Handle negative 0.0. |
| 99 if (this == 0.0) return 0.0; | 116 if (this == 0.0) return 0.0; |
| 100 return this < 0.0 ? -this : this; | 117 return this < 0.0 ? -this : this; |
| 101 } | 118 } |
| 102 | 119 |
| 103 double get sign { | 120 double get sign { |
| 104 if (this > 0.0) return 1.0; | 121 if (this > 0.0) return 1.0; |
| 105 if (this < 0.0) return -1.0; | 122 if (this < 0.0) return -1.0; |
| 106 return this; // +/-0.0 or NaN. | 123 return this; // +/-0.0 or NaN. |
| 107 } | 124 } |
| 108 | 125 |
| 109 int round() => roundToDouble().toInt(); | 126 int round() => roundToDouble().toInt(); |
| 110 int floor() => floorToDouble().toInt(); | 127 int floor() => floorToDouble().toInt(); |
| 111 int ceil () => ceilToDouble().toInt(); | 128 int ceil() => ceilToDouble().toInt(); |
| 112 int truncate() => truncateToDouble().toInt(); | 129 int truncate() => truncateToDouble().toInt(); |
| 113 | 130 |
| 114 double roundToDouble() native "Double_round"; | 131 double roundToDouble() native "Double_round"; |
| 115 double floorToDouble() native "Double_floor"; | 132 double floorToDouble() native "Double_floor"; |
| 116 double ceilToDouble() native "Double_ceil"; | 133 double ceilToDouble() native "Double_ceil"; |
| 117 double truncateToDouble() native "Double_truncate"; | 134 double truncateToDouble() native "Double_truncate"; |
| 118 | 135 |
| 119 num clamp(num lowerLimit, num upperLimit) { | 136 num clamp(num lowerLimit, num upperLimit) { |
| 120 if (lowerLimit is! num) { | 137 if (lowerLimit is! num) { |
| 121 throw new ArgumentError.value(lowerLimit, "lowerLimit", "not a number"); | 138 throw new ArgumentError.value(lowerLimit, "lowerLimit", "not a number"); |
| 122 } | 139 } |
| 123 if (upperLimit is! num) { | 140 if (upperLimit is! num) { |
| 124 throw new ArgumentError.value(upperLimit, "upperLimit", "not a number"); | 141 throw new ArgumentError.value(upperLimit, "upperLimit", "not a number"); |
| 125 } | 142 } |
| 126 | 143 |
| 127 if (lowerLimit.compareTo(upperLimit) > 0) { | 144 if (lowerLimit.compareTo(upperLimit) > 0) { |
| 128 throw new ArgumentError(lowerLimit); | 145 throw new ArgumentError(lowerLimit); |
| 129 } | 146 } |
| 130 if (lowerLimit.isNaN) return lowerLimit; | 147 if (lowerLimit.isNaN) return lowerLimit; |
| 131 if (this.compareTo(lowerLimit) < 0) return lowerLimit; | 148 if (this.compareTo(lowerLimit) < 0) return lowerLimit; |
| 132 if (this.compareTo(upperLimit) > 0) return upperLimit; | 149 if (this.compareTo(upperLimit) > 0) return upperLimit; |
| 133 return this; | 150 return this; |
| 134 } | 151 } |
| 135 | 152 |
| 136 int toInt() native "Double_toInt"; | 153 int toInt() native "Double_toInt"; |
| 137 num _toBigintOrDouble() { return this; } | 154 num _toBigintOrDouble() { |
| 138 double toDouble() { return this; } | 155 return this; |
| 156 } |
| 157 |
| 158 double toDouble() { |
| 159 return this; |
| 160 } |
| 139 | 161 |
| 140 static const int CACHE_SIZE_LOG2 = 3; | 162 static const int CACHE_SIZE_LOG2 = 3; |
| 141 static const int CACHE_LENGTH = 1 << (CACHE_SIZE_LOG2 + 1); | 163 static const int CACHE_LENGTH = 1 << (CACHE_SIZE_LOG2 + 1); |
| 142 static const int CACHE_MASK = CACHE_LENGTH - 1; | 164 static const int CACHE_MASK = CACHE_LENGTH - 1; |
| 143 // Each key (double) followed by its toString result. | 165 // Each key (double) followed by its toString result. |
| 144 static final List _cache = new List(CACHE_LENGTH); | 166 static final List _cache = new List(CACHE_LENGTH); |
| 145 static int _cacheEvictIndex = 0; | 167 static int _cacheEvictIndex = 0; |
| 146 | 168 |
| 147 String _toString() native "Double_toString"; | 169 String _toString() native "Double_toString"; |
| 148 | 170 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 | 208 |
| 187 // Step 5 and 6 skipped. Will be dealt with by native function. | 209 // Step 5 and 6 skipped. Will be dealt with by native function. |
| 188 | 210 |
| 189 // Step 7. | 211 // Step 7. |
| 190 if (x >= 1e21 || x <= -1e21) { | 212 if (x >= 1e21 || x <= -1e21) { |
| 191 return x.toString(); | 213 return x.toString(); |
| 192 } | 214 } |
| 193 | 215 |
| 194 return _toStringAsFixed(fractionDigits); | 216 return _toStringAsFixed(fractionDigits); |
| 195 } | 217 } |
| 218 |
| 196 String _toStringAsFixed(int fractionDigits) native "Double_toStringAsFixed"; | 219 String _toStringAsFixed(int fractionDigits) native "Double_toStringAsFixed"; |
| 197 | 220 |
| 198 String toStringAsExponential([int fractionDigits]) { | 221 String toStringAsExponential([int fractionDigits]) { |
| 199 // See ECMAScript-262, 15.7.4.6 for details. | 222 // See ECMAScript-262, 15.7.4.6 for details. |
| 200 | 223 |
| 201 // The EcmaScript specification checks for NaN and Infinity before looking | 224 // The EcmaScript specification checks for NaN and Infinity before looking |
| 202 // at the fractionDigits. In Dart we are consistent with toStringAsFixed and | 225 // at the fractionDigits. In Dart we are consistent with toStringAsFixed and |
| 203 // look at the fractionDigits first. | 226 // look at the fractionDigits first. |
| 204 | 227 |
| 205 // Step 7. | 228 // Step 7. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 216 if (isNaN) return "NaN"; | 239 if (isNaN) return "NaN"; |
| 217 if (this == double.INFINITY) return "Infinity"; | 240 if (this == double.INFINITY) return "Infinity"; |
| 218 if (this == -double.INFINITY) return "-Infinity"; | 241 if (this == -double.INFINITY) return "-Infinity"; |
| 219 | 242 |
| 220 // The dart function prints the shortest representation when fractionDigits | 243 // The dart function prints the shortest representation when fractionDigits |
| 221 // equals null. The native function wants -1 instead. | 244 // equals null. The native function wants -1 instead. |
| 222 fractionDigits = (fractionDigits == null) ? -1 : fractionDigits; | 245 fractionDigits = (fractionDigits == null) ? -1 : fractionDigits; |
| 223 | 246 |
| 224 return _toStringAsExponential(fractionDigits); | 247 return _toStringAsExponential(fractionDigits); |
| 225 } | 248 } |
| 249 |
| 226 String _toStringAsExponential(int fractionDigits) | 250 String _toStringAsExponential(int fractionDigits) |
| 227 native "Double_toStringAsExponential"; | 251 native "Double_toStringAsExponential"; |
| 228 | 252 |
| 229 String toStringAsPrecision(int precision) { | 253 String toStringAsPrecision(int precision) { |
| 230 // See ECMAScript-262, 15.7.4.7 for details. | 254 // See ECMAScript-262, 15.7.4.7 for details. |
| 231 | 255 |
| 232 // The EcmaScript specification checks for NaN and Infinity before looking | 256 // The EcmaScript specification checks for NaN and Infinity before looking |
| 233 // at the fractionDigits. In Dart we are consistent with toStringAsFixed and | 257 // at the fractionDigits. In Dart we are consistent with toStringAsFixed and |
| 234 // look at the fractionDigits first. | 258 // look at the fractionDigits first. |
| 235 | 259 |
| 236 if (precision is! int) { | 260 if (precision is! int) { |
| 237 throw new ArgumentError.value(precision, "precision", "not an integer"); | 261 throw new ArgumentError.value(precision, "precision", "not an integer"); |
| 238 } | 262 } |
| 239 // Step 8. | 263 // Step 8. |
| 240 if (precision < 1 || precision > 21) { | 264 if (precision < 1 || precision > 21) { |
| 241 throw new RangeError.range(precision, 1, 21, "precision"); | 265 throw new RangeError.range(precision, 1, 21, "precision"); |
| 242 } | 266 } |
| 243 | 267 |
| 244 if (isNaN) return "NaN"; | 268 if (isNaN) return "NaN"; |
| 245 if (this == double.INFINITY) return "Infinity"; | 269 if (this == double.INFINITY) return "Infinity"; |
| 246 if (this == -double.INFINITY) return "-Infinity"; | 270 if (this == -double.INFINITY) return "-Infinity"; |
| 247 | 271 |
| 248 return _toStringAsPrecision(precision); | 272 return _toStringAsPrecision(precision); |
| 249 } | 273 } |
| 274 |
| 250 String _toStringAsPrecision(int fractionDigits) | 275 String _toStringAsPrecision(int fractionDigits) |
| 251 native "Double_toStringAsPrecision"; | 276 native "Double_toStringAsPrecision"; |
| 252 | 277 |
| 253 // Order is: NaN > Infinity > ... > 0.0 > -0.0 > ... > -Infinity. | 278 // Order is: NaN > Infinity > ... > 0.0 > -0.0 > ... > -Infinity. |
| 254 int compareTo(num other) { | 279 int compareTo(num other) { |
| 255 const int EQUAL = 0, LESS = -1, GREATER = 1; | 280 const int EQUAL = 0, LESS = -1, GREATER = 1; |
| 256 if (this < other) { | 281 if (this < other) { |
| 257 return LESS; | 282 return LESS; |
| 258 } else if (this > other) { | 283 } else if (this > other) { |
| 259 return GREATER; | 284 return GREATER; |
| 260 } else if (this == other) { | 285 } else if (this == other) { |
| 261 if (this == 0.0) { | 286 if (this == 0.0) { |
| 262 bool thisIsNegative = isNegative; | 287 bool thisIsNegative = isNegative; |
| 263 bool otherIsNegative = other.isNegative; | 288 bool otherIsNegative = other.isNegative; |
| 264 if (thisIsNegative == otherIsNegative) { | 289 if (thisIsNegative == otherIsNegative) { |
| 265 return EQUAL; | 290 return EQUAL; |
| 266 } | 291 } |
| 267 return thisIsNegative ? LESS : GREATER; | 292 return thisIsNegative ? LESS : GREATER; |
| 268 } else { | 293 } else { |
| 269 return EQUAL; | 294 return EQUAL; |
| 270 } | 295 } |
| 271 } else if (isNaN) { | 296 } else if (isNaN) { |
| 272 return other.isNaN ? EQUAL : GREATER; | 297 return other.isNaN ? EQUAL : GREATER; |
| 273 } else { | 298 } else { |
| 274 // Other is NaN. | 299 // Other is NaN. |
| 275 return LESS; | 300 return LESS; |
| 276 } | 301 } |
| 277 } | 302 } |
| 278 } | 303 } |
| OLD | NEW |