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