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) |
7 native "Double_doubleFromInteger"; | 7 native "Double_doubleFromInteger"; |
8 int get hashCode { | 8 int get hashCode { |
9 try { | 9 if (isNaN || isInfinite) return 0; |
10 return toInt(); | 10 return toInt(); |
11 } on FormatException catch (e) { | |
12 return 0; | |
13 } | |
14 } | 11 } |
15 double operator +(num other) { | 12 double operator +(num other) { |
16 return _add(other.toDouble()); | 13 return _add(other.toDouble()); |
17 } | 14 } |
18 double _add(double other) native "Double_add"; | 15 double _add(double other) native "Double_add"; |
19 | 16 |
20 double operator -(num other) { | 17 double operator -(num other) { |
21 return _sub(other.toDouble()); | 18 return _sub(other.toDouble()); |
22 } | 19 } |
23 double _sub(double other) native "Double_sub"; | 20 double _sub(double other) native "Double_sub"; |
24 | 21 |
25 double operator *(num other) { | 22 double operator *(num other) { |
26 return _mul(other.toDouble()); | 23 return _mul(other.toDouble()); |
27 } | 24 } |
28 double _mul(double other) native "Double_mul"; | 25 double _mul(double other) native "Double_mul"; |
29 | 26 |
30 double operator ~/(num other) { | 27 int operator ~/(num other) { |
31 return _trunc_div(other.toDouble()); | 28 return _trunc_div(other.toDouble()); |
32 } | 29 } |
33 double _trunc_div(double other) native "Double_trunc_div"; | 30 int _trunc_div(double other) native "Double_trunc_div"; |
34 | 31 |
35 double operator /(num other) { | 32 double operator /(num other) { |
36 return _div(other.toDouble()); | 33 return _div(other.toDouble()); |
37 } | 34 } |
38 double _div(double other) native "Double_div"; | 35 double _div(double other) native "Double_div"; |
39 | 36 |
40 double operator %(num other) { | 37 double operator %(num other) { |
41 return _modulo(other.toDouble()); | 38 return _modulo(other.toDouble()); |
42 } | 39 } |
43 double _modulo(double other) native "Double_modulo"; | 40 double _modulo(double other) native "Double_modulo"; |
(...skipping 30 matching lines...) Expand all Loading... |
74 } | 71 } |
75 double _addFromInteger(int other) { | 72 double _addFromInteger(int other) { |
76 return new _Double.fromInteger(other) + this; | 73 return new _Double.fromInteger(other) + this; |
77 } | 74 } |
78 double _subFromInteger(int other) { | 75 double _subFromInteger(int other) { |
79 return new _Double.fromInteger(other) - this; | 76 return new _Double.fromInteger(other) - this; |
80 } | 77 } |
81 double _mulFromInteger(int other) { | 78 double _mulFromInteger(int other) { |
82 return new _Double.fromInteger(other) * this; | 79 return new _Double.fromInteger(other) * this; |
83 } | 80 } |
84 double _truncDivFromInteger(int other) { | 81 int _truncDivFromInteger(int other) { |
85 return new _Double.fromInteger(other) ~/ this; | 82 return new _Double.fromInteger(other) ~/ this; |
86 } | 83 } |
87 double _moduloFromInteger(int other) { | 84 double _moduloFromInteger(int other) { |
88 return new _Double.fromInteger(other) % this; | 85 return new _Double.fromInteger(other) % this; |
89 } | 86 } |
90 double _remainderFromInteger(int other) { | 87 double _remainderFromInteger(int other) { |
91 return new _Double.fromInteger(other).remainder(this); | 88 return new _Double.fromInteger(other).remainder(this); |
92 } | 89 } |
93 bool _greaterThanFromInteger(int other) | 90 bool _greaterThanFromInteger(int other) |
94 native "Double_greaterThanFromInteger"; | 91 native "Double_greaterThanFromInteger"; |
95 | 92 |
96 bool get isNegative native "Double_getIsNegative"; | 93 bool get isNegative native "Double_getIsNegative"; |
97 bool get isInfinite native "Double_getIsInfinite"; | 94 bool get isInfinite native "Double_getIsInfinite"; |
98 bool get isNaN native "Double_getIsNaN"; | 95 bool get isNaN native "Double_getIsNaN"; |
99 | 96 |
100 double abs() { | 97 double abs() { |
101 // Handle negative 0.0. | 98 // Handle negative 0.0. |
102 if (this == 0.0) return 0.0; | 99 if (this == 0.0) return 0.0; |
103 return this < 0.0 ? -this : this; | 100 return this < 0.0 ? -this : this; |
104 } | 101 } |
105 | 102 |
106 double round() native "Double_round"; | 103 double round() native "Double_round"; |
107 double floor() native "Double_floor"; | 104 double floor() native "Double_floor"; |
108 double ceil () native "Double_ceil"; | 105 double ceil () native "Double_ceil"; |
109 double truncate() native "Double_truncate"; | 106 double truncate() native "Double_truncate"; |
| 107 |
| 108 num clamp(num lowerLimit, num upperLimit) { |
| 109 if (lowerLimit is! num) throw new ArgumentError(lowerLimit); |
| 110 if (upperLimit is! num) throw new ArgumentError(upperLimit); |
| 111 |
| 112 if (lowerLimit.compareTo(upperLimit) > 0) { |
| 113 throw new ArgumentError(lowerLimit); |
| 114 } |
| 115 if (lowerLimit.isNaN) return lowerLimit; |
| 116 if (this.compareTo(lowerLimit) < 0) return lowerLimit; |
| 117 if (this.compareTo(upperLimit) > 0) return upperLimit; |
| 118 return this; |
| 119 } |
| 120 |
110 int toInt() native "Double_toInt"; | 121 int toInt() native "Double_toInt"; |
111 double toDouble() { return this; } | 122 double toDouble() { return this; } |
112 | 123 |
113 double pow(num exponent) { | 124 double pow(num exponent) { |
114 if (exponent == 0) { | 125 if (exponent == 0) { |
115 return 1.0; // ECMA-262 15.8.2.13 | 126 return 1.0; // ECMA-262 15.8.2.13 |
116 } | 127 } |
117 if (exponent is! num) { | 128 if (exponent is! num) { |
118 throw new ArgumentError(null); | 129 throw new ArgumentError(null); |
119 } | 130 } |
120 double doubleExponent = exponent.toDouble(); | 131 double doubleExponent = exponent.toDouble(); |
121 if (isNaN || exponent.isNaN) { | 132 if (isNaN || exponent.isNaN) { |
122 return double.NAN; | 133 return double.NAN; |
123 } | 134 } |
124 return _pow(doubleExponent); | 135 return _pow(doubleExponent); |
125 } | 136 } |
126 double _pow(double exponent) native "Double_pow"; | 137 double _pow(double exponent) native "Double_pow"; |
127 | 138 |
128 String toStringAsFixed(int fractionDigits) { | 139 String toStringAsFixed(int fractionDigits) { |
129 // See ECMAScript-262, 15.7.4.5 for details. | 140 // See ECMAScript-262, 15.7.4.5 for details. |
130 | 141 |
| 142 if (fractionDigits is! int) { |
| 143 throw new ArgumentError(fractionDigits); |
| 144 } |
131 // Step 2. | 145 // Step 2. |
132 if (fractionDigits < 0 || fractionDigits > 20) { | 146 if (fractionDigits < 0 || fractionDigits > 20) { |
133 // TODO(antonm): should be proper RangeError or Dart counterpart. | 147 throw new RangeError(fractionDigits); |
134 throw "Range error"; | |
135 } | 148 } |
136 | 149 |
137 // Step 3. | 150 // Step 3. |
138 double x = this; | 151 double x = this; |
139 | 152 |
140 // Step 4. | 153 // Step 4. |
141 if (isNaN) return "NaN"; | 154 if (isNaN) return "NaN"; |
142 | 155 |
143 // Step 5 and 6 skipped. Will be dealt with by native function. | 156 // Step 5 and 6 skipped. Will be dealt with by native function. |
144 | 157 |
145 // Step 7. | 158 // Step 7. |
146 if (x >= 1e21 || x <= -1e21) { | 159 if (x >= 1e21 || x <= -1e21) { |
147 return x.toString(); | 160 return x.toString(); |
148 } | 161 } |
149 | 162 |
150 return _toStringAsFixed(fractionDigits); | 163 return _toStringAsFixed(fractionDigits); |
151 } | 164 } |
152 String _toStringAsFixed(int fractionDigits) native "Double_toStringAsFixed"; | 165 String _toStringAsFixed(int fractionDigits) native "Double_toStringAsFixed"; |
153 | 166 |
154 String toStringAsExponential(int fractionDigits) { | 167 String toStringAsExponential([int fractionDigits]) { |
155 // See ECMAScript-262, 15.7.4.6 for details. | 168 // See ECMAScript-262, 15.7.4.6 for details. |
156 | 169 |
157 // The EcmaScript specification checks for NaN and Infinity before looking | 170 // The EcmaScript specification checks for NaN and Infinity before looking |
158 // at the fractionDigits. In Dart we are consistent with toStringAsFixed and | 171 // at the fractionDigits. In Dart we are consistent with toStringAsFixed and |
159 // look at the fractionDigits first. | 172 // look at the fractionDigits first. |
160 | 173 |
161 // Step 7. | 174 // Step 7. |
162 if (fractionDigits != null && | 175 if (fractionDigits != null) { |
163 (fractionDigits < 0 || fractionDigits > 20)) { | 176 if (fractionDigits is! int) { |
164 // TODO(antonm): should be proper RangeError or Dart counterpart. | 177 throw new ArgumentError(fractionDigits); |
165 throw "Range error"; | 178 } |
| 179 if (fractionDigits < 0 || fractionDigits > 20) { |
| 180 throw new RangeError(fractionDigits); |
| 181 } |
166 } | 182 } |
167 | 183 |
168 if (isNaN) return "NaN"; | 184 if (isNaN) return "NaN"; |
169 if (this == double.INFINITY) return "Infinity"; | 185 if (this == double.INFINITY) return "Infinity"; |
170 if (this == -double.INFINITY) return "-Infinity"; | 186 if (this == -double.INFINITY) return "-Infinity"; |
171 | 187 |
172 // The dart function prints the shortest representation when fractionDigits | 188 // The dart function prints the shortest representation when fractionDigits |
173 // equals null. The native function wants -1 instead. | 189 // equals null. The native function wants -1 instead. |
174 fractionDigits = (fractionDigits == null) ? -1 : fractionDigits; | 190 fractionDigits = (fractionDigits == null) ? -1 : fractionDigits; |
175 | 191 |
176 return _toStringAsExponential(fractionDigits); | 192 return _toStringAsExponential(fractionDigits); |
177 } | 193 } |
178 String _toStringAsExponential(int fractionDigits) | 194 String _toStringAsExponential(int fractionDigits) |
179 native "Double_toStringAsExponential"; | 195 native "Double_toStringAsExponential"; |
180 | 196 |
181 String toStringAsPrecision(int precision) { | 197 String toStringAsPrecision(int precision) { |
182 // See ECMAScript-262, 15.7.4.7 for details. | 198 // See ECMAScript-262, 15.7.4.7 for details. |
183 | 199 |
184 // The EcmaScript specification checks for NaN and Infinity before looking | 200 // The EcmaScript specification checks for NaN and Infinity before looking |
185 // at the fractionDigits. In Dart we are consistent with toStringAsFixed and | 201 // at the fractionDigits. In Dart we are consistent with toStringAsFixed and |
186 // look at the fractionDigits first. | 202 // look at the fractionDigits first. |
187 | 203 |
| 204 if (precision is! int) throw new ArgumentError(precision); |
| 205 |
188 // Step 8. | 206 // Step 8. |
189 if (precision < 1 || precision > 21) { | 207 if (precision < 1 || precision > 21) { |
190 // TODO(antonm): should be proper RangeError or Dart counterpart. | 208 throw new RangeError(precision); |
191 throw "Range error"; | |
192 } | 209 } |
193 | 210 |
194 if (isNaN) return "NaN"; | 211 if (isNaN) return "NaN"; |
195 if (this == double.INFINITY) return "Infinity"; | 212 if (this == double.INFINITY) return "Infinity"; |
196 if (this == -double.INFINITY) return "-Infinity"; | 213 if (this == -double.INFINITY) return "-Infinity"; |
197 | 214 |
198 return _toStringAsPrecision(precision); | 215 return _toStringAsPrecision(precision); |
199 } | 216 } |
200 String _toStringAsPrecision(int fractionDigits) | 217 String _toStringAsPrecision(int fractionDigits) |
201 native "Double_toStringAsPrecision"; | 218 native "Double_toStringAsPrecision"; |
202 | 219 |
203 String toRadixString(int radix) { | |
204 return toInt().toRadixString(radix); | |
205 } | |
206 | |
207 // Order is: NaN > Infinity > ... > 0.0 > -0.0 > ... > -Infinity. | 220 // Order is: NaN > Infinity > ... > 0.0 > -0.0 > ... > -Infinity. |
208 int compareTo(Comparable other) { | 221 int compareTo(Comparable other) { |
209 final int EQUAL = 0, LESS = -1, GREATER = 1; | 222 final int EQUAL = 0, LESS = -1, GREATER = 1; |
210 if (this < other) { | 223 if (this < other) { |
211 return LESS; | 224 return LESS; |
212 } else if (this > other) { | 225 } else if (this > other) { |
213 return GREATER; | 226 return GREATER; |
214 } else if (this == other) { | 227 } else if (this == other) { |
215 if (this == 0.0) { | 228 if (this == 0.0) { |
216 bool thisIsNegative = isNegative; | 229 bool thisIsNegative = isNegative; |
217 bool otherIsNegative = other.isNegative; | 230 bool otherIsNegative = other.isNegative; |
218 if (thisIsNegative == otherIsNegative) { | 231 if (thisIsNegative == otherIsNegative) { |
219 return EQUAL; | 232 return EQUAL; |
220 } | 233 } |
221 return thisIsNegative ? LESS : GREATER; | 234 return thisIsNegative ? LESS : GREATER; |
222 } else { | 235 } else { |
223 return EQUAL; | 236 return EQUAL; |
224 } | 237 } |
225 } else if (isNaN) { | 238 } else if (isNaN) { |
226 return other.isNaN ? EQUAL : GREATER; | 239 return other.isNaN ? EQUAL : GREATER; |
227 } else { | 240 } else { |
228 // Other is NaN. | 241 // Other is NaN. |
229 return LESS; | 242 return LESS; |
230 } | 243 } |
231 } | 244 } |
232 } | 245 } |
OLD | NEW |