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 part of fixnum; | 5 part of fixnum; |
6 | 6 |
7 /** | 7 /** |
8 * An immutable 32-bit signed integer, in the range [-2^31, 2^31 - 1]. | 8 * An immutable 32-bit signed integer, in the range [-2^31, 2^31 - 1]. |
9 * Arithmetic operations may overflow in order to maintain this range. | 9 * Arithmetic operations may overflow in order to maintain this range. |
10 */ | 10 */ |
11 class int32 implements intx { | 11 class int32 implements intx { |
justinfagnani
2013/07/26 23:44:40
btw, I should have mentioned this last review, but
Chris Bracken
2013/07/27 01:07:11
Agreed - will create a separate CL for this to avo
| |
12 | 12 |
13 /** | 13 /** |
14 * The maximum positive value attainable by an [int32], namely | 14 * The maximum positive value attainable by an [int32], namely |
15 * 2147483647. | 15 * 2147483647. |
16 */ | 16 */ |
17 static const int32 MAX_VALUE = const int32._internal(0x7FFFFFFF); | 17 static const int32 MAX_VALUE = const int32._internal(0x7FFFFFFF); |
18 | 18 |
19 /** | 19 /** |
20 * The minimum positive value attainable by an [int32], namely | 20 * The minimum positive value attainable by an [int32], namely |
21 * -2147483648. | 21 * -2147483648. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 final int _i; | 131 final int _i; |
132 | 132 |
133 const int32._internal(int i) : _i = i; | 133 const int32._internal(int i) : _i = i; |
134 | 134 |
135 /** | 135 /** |
136 * Constructs an [int32] from an [int]. Only the low 32 bits of the input | 136 * Constructs an [int32] from an [int]. Only the low 32 bits of the input |
137 * are used. | 137 * are used. |
138 */ | 138 */ |
139 int32.fromInt(int i) : _i = (i & 0x7fffffff) - (i & 0x80000000); | 139 int32.fromInt(int i) : _i = (i & 0x7fffffff) - (i & 0x80000000); |
140 | 140 |
141 // Convert an [int] or [intx] to an [int32]. Note that an [int64] | 141 // Returns the [int] representation of the specified value or null for |
142 // will be truncated. | 142 // incompatible types. |
143 int _convert(other) { | 143 int _toInt(val) { |
justinfagnani
2013/07/26 23:44:40
all uses of this exception the one in ==() throw a
Chris Bracken
2013/07/27 01:07:11
Done.
| |
144 if (other == null) { | 144 if (val is int32) { |
145 throw new ArgumentError(null); | 145 return val._i; |
146 } else if (other is intx) { | 146 } else if (val is int) { |
147 return other.toInt32()._i; | 147 return val; |
148 } else if (other is int) { | |
149 return other; | |
150 } else { | |
151 throw new Exception("Can't retrieve 32-bit int from $other"); | |
152 } | 148 } |
149 return null; | |
153 } | 150 } |
154 | 151 |
155 // The +, -, * , &, |, and ^ operaters deal with types as follows: | 152 // The +, -, * , &, |, and ^ operaters deal with types as follows: |
156 // | 153 // |
157 // int32 + int => int32 | 154 // int32 + int => int32 |
158 // int32 + int32 => int32 | 155 // int32 + int32 => int32 |
159 // int32 + int64 => int64 | 156 // int32 + int64 => int64 |
160 // | 157 // |
161 // The %, ~/ and remainder operators return an int32 even with an int64 | 158 // The %, ~/ and remainder operators return an int32 even with an int64 |
162 // argument, since the result cannot be greater than the value on the | 159 // argument, since the result cannot be greater than the value on the |
163 // left-hand side: | 160 // left-hand side: |
164 // | 161 // |
165 // int32 % int => int32 | 162 // int32 % int => int32 |
166 // int32 % int32 => int32 | 163 // int32 % int32 => int32 |
167 // int32 % int64 => int32 | 164 // int32 % int64 => int32 |
168 | 165 |
169 intx operator +(other) { | 166 intx operator +(other) { |
170 if (other is int64) { | 167 if (other is int64) { |
171 return this.toInt64() + other; | 168 return this.toInt64() + other; |
justinfagnani
2013/07/26 23:44:40
for all these "this.toInt64()" calls, can you inst
Chris Bracken
2013/07/27 01:07:11
Done.
Chris Bracken
2013/07/27 01:07:11
As the code currently stands, it won't help. int64
| |
172 } | 169 } |
173 return new int32.fromInt(_i + _convert(other)); | 170 var intVal = _toInt(other); |
171 if (intVal != null) { | |
172 return new int32.fromInt(_i + intVal); | |
173 } | |
174 throw new ArgumentError(other); | |
174 } | 175 } |
175 | 176 |
176 intx operator -(other) { | 177 intx operator -(other) { |
177 if (other is int64) { | 178 if (other is int64) { |
178 return this.toInt64() - other; | 179 return this.toInt64() - other; |
179 } | 180 } |
180 return new int32.fromInt(_i - _convert(other)); | 181 var intVal = _toInt(other); |
182 if (intVal != null) { | |
183 return new int32.fromInt(_i - intVal); | |
184 } | |
185 throw new ArgumentError(other); | |
181 } | 186 } |
182 | 187 |
183 int32 operator -() => new int32.fromInt(-_i); | 188 int32 operator -() => new int32.fromInt(-_i); |
184 | 189 |
185 intx operator *(other) { | 190 intx operator *(other) { |
186 if (other is int64) { | 191 if (other is int64) { |
187 return this.toInt64() * other; | 192 return this.toInt64() * other; |
188 } | 193 } |
189 // TODO(rice) - optimize | 194 // TODO(rice) - optimize |
190 return (this.toInt64() * other).toInt32(); | 195 return (this.toInt64() * other).toInt32(); |
191 } | 196 } |
192 | 197 |
193 int32 operator %(other) { | 198 int32 operator %(other) { |
194 if (other is int64) { | 199 if (other is int64) { |
195 // Result will be int32 | 200 // Result will be int32 |
196 return (this.toInt64() % other).toInt32(); | 201 return (this.toInt64() % other).toInt32(); |
197 } | 202 } |
198 return new int32.fromInt(_i % _convert(other)); | 203 var intVal = _toInt(other); |
204 if (intVal != null) { | |
205 return new int32.fromInt(_i % intVal); | |
206 } | |
207 throw new ArgumentError(other); | |
199 } | 208 } |
200 | 209 |
201 int32 operator ~/(other) { | 210 int32 operator ~/(other) { |
202 if (other is int64) { | 211 if (other is int64) { |
203 // Result will be int32 | |
204 return (this.toInt64() ~/ other).toInt32(); | 212 return (this.toInt64() ~/ other).toInt32(); |
205 } | 213 } |
206 return new int32.fromInt(_i ~/ _convert(other)); | 214 var intVal = _toInt(other); |
215 if (intVal != null) { | |
216 return new int32.fromInt(_i ~/ intVal); | |
217 } | |
218 throw new ArgumentError(other); | |
207 } | 219 } |
208 | 220 |
209 int32 remainder(other) { | 221 int32 remainder(other) { |
210 if (other is int64) { | 222 if (other is int64) { |
211 // Result will be int32 | |
212 int64 t = this.toInt64(); | 223 int64 t = this.toInt64(); |
213 return (t - (t ~/ other) * other).toInt32(); | 224 return (t - (t ~/ other) * other).toInt32(); |
214 } | 225 } |
215 return this - (this ~/ other) * other; | 226 return this - (this ~/ other) * other; |
216 } | 227 } |
217 | 228 |
218 int32 operator &(other) { | 229 int32 operator &(other) { |
219 if (other is int64) { | 230 if (other is int64) { |
220 return (this.toInt64() & other).toInt32(); | 231 return (this.toInt64() & other).toInt32(); |
221 } | 232 } |
222 return new int32.fromInt(_i & _convert(other)); | 233 var intVal = _toInt(other); |
234 if (intVal != null) { | |
235 return new int32.fromInt(_i & intVal); | |
236 } | |
237 throw new ArgumentError(other); | |
223 } | 238 } |
224 | 239 |
225 int32 operator |(other) { | 240 int32 operator |(other) { |
226 if (other is int64) { | 241 if (other is int64) { |
227 return (this.toInt64() | other).toInt32(); | 242 return (this.toInt64() | other).toInt32(); |
228 } | 243 } |
229 return new int32.fromInt(_i | _convert(other)); | 244 var intVal = _toInt(other); |
245 if (intVal != null) { | |
246 return new int32.fromInt(_i | intVal); | |
247 } | |
248 throw new ArgumentError(other); | |
230 } | 249 } |
231 | 250 |
232 int32 operator ^(other) { | 251 int32 operator ^(other) { |
233 if (other is int64) { | 252 if (other is int64) { |
234 return (this.toInt64() ^ other).toInt32(); | 253 return (this.toInt64() ^ other).toInt32(); |
235 } | 254 } |
236 return new int32.fromInt(_i ^ _convert(other)); | 255 var intVal = _toInt(other); |
256 if (intVal != null) { | |
257 return new int32.fromInt(_i ^ intVal); | |
258 } | |
259 throw new ArgumentError(other); | |
237 } | 260 } |
238 | 261 |
239 int32 operator ~() => new int32.fromInt(~_i); | 262 int32 operator ~() => new int32.fromInt(~_i); |
240 | 263 |
241 int32 operator <<(int n) { | 264 int32 operator <<(int n) { |
242 if (n < 0) { | 265 if (n < 0) { |
243 throw new ArgumentError("$n"); | 266 throw new ArgumentError("$n"); |
244 } | 267 } |
245 n &= 31; | 268 n &= 31; |
246 return new int32.fromInt(_i << n); | 269 return new int32.fromInt(_i << n); |
(...skipping 25 matching lines...) Expand all Loading... | |
272 value = (_i >> n) & ((1 << (32 - n)) - 1); | 295 value = (_i >> n) & ((1 << (32 - n)) - 1); |
273 } | 296 } |
274 return new int32.fromInt(value); | 297 return new int32.fromInt(value); |
275 } | 298 } |
276 | 299 |
277 /** | 300 /** |
278 * Returns [true] if this [int32] has the same numeric value as the | 301 * Returns [true] if this [int32] has the same numeric value as the |
279 * given object. The argument may be an [int] or an [intx]. | 302 * given object. The argument may be an [int] or an [intx]. |
280 */ | 303 */ |
281 bool operator ==(other) { | 304 bool operator ==(other) { |
282 if (other == null) { | |
283 return false; | |
284 } | |
285 if (other is int64) { | 305 if (other is int64) { |
286 return this.toInt64() == other; | 306 return this.toInt64() == other; |
287 } | 307 } |
288 return _i == _convert(other); | 308 return _i == _toInt(other); |
289 } | 309 } |
290 | 310 |
291 int compareTo(Comparable other) { | 311 int compareTo(Comparable other) { |
292 if (other is int64) { | 312 if (other is int64) { |
293 return this.toInt64().compareTo(other); | 313 return this.toInt64().compareTo(other); |
294 } | 314 } |
295 return _i.compareTo(_convert(other)); | 315 var intVal = _toInt(other); |
316 if (intVal != null) { | |
317 return _i.compareTo(intVal); | |
318 } | |
319 throw new ArgumentError(other); | |
296 } | 320 } |
297 | 321 |
298 bool operator <(other) { | 322 bool operator <(other) { |
299 if (other is int64) { | 323 if (other is int64) { |
300 return this.toInt64() < other; | 324 return this.toInt64() < other; |
301 } | 325 } |
302 return _i < _convert(other); | 326 var intVal = _toInt(other); |
327 if (intVal != null) { | |
328 return _i < intVal; | |
329 } | |
330 throw new ArgumentError(other); | |
331 | |
303 } | 332 } |
304 | 333 |
305 bool operator <=(other) { | 334 bool operator <=(other) { |
306 if (other is int64) { | 335 if (other is int64) { |
307 return this.toInt64() < other; | 336 return this.toInt64() < other; |
308 } | 337 } |
309 return _i <= _convert(other); | 338 var intVal = _toInt(other); |
339 if (intVal != null) { | |
340 return _i <= intVal; | |
341 } | |
342 throw new ArgumentError(other); | |
310 } | 343 } |
311 | 344 |
312 bool operator >(other) { | 345 bool operator >(other) { |
313 if (other is int64) { | 346 if (other is int64) { |
314 return this.toInt64() < other; | 347 return this.toInt64() < other; |
315 } | 348 } |
316 return _i > _convert(other); | 349 var intVal = _toInt(other); |
350 if (intVal != null) { | |
351 return _i > intVal; | |
352 } | |
353 throw new ArgumentError(other); | |
354 | |
317 } | 355 } |
318 | 356 |
319 bool operator >=(other) { | 357 bool operator >=(other) { |
320 if (other is int64) { | 358 if (other is int64) { |
321 return this.toInt64() < other; | 359 return this.toInt64() < other; |
322 } | 360 } |
323 return _i >= _convert(other); | 361 var intVal = _toInt(other); |
362 if (intVal != null) { | |
363 return _i >= intVal; | |
364 } | |
365 throw new ArgumentError(other); | |
324 } | 366 } |
325 | 367 |
326 bool get isEven => (_i & 0x1) == 0; | 368 bool get isEven => (_i & 0x1) == 0; |
327 bool get isMaxValue => _i == 2147483647; | 369 bool get isMaxValue => _i == 2147483647; |
328 bool get isMinValue => _i == -2147483648; | 370 bool get isMinValue => _i == -2147483648; |
329 bool get isNegative => _i < 0; | 371 bool get isNegative => _i < 0; |
330 bool get isOdd => (_i & 0x1) == 1; | 372 bool get isOdd => (_i & 0x1) == 1; |
331 bool get isZero => _i == 0; | 373 bool get isZero => _i == 0; |
332 | 374 |
333 int get hashCode => _i; | 375 int get hashCode => _i; |
(...skipping 13 matching lines...) Expand all Loading... | |
347 } | 389 } |
348 | 390 |
349 int toInt() => _i; | 391 int toInt() => _i; |
350 int32 toInt32() => this; | 392 int32 toInt32() => this; |
351 int64 toInt64() => new int64.fromInt(_i); | 393 int64 toInt64() => new int64.fromInt(_i); |
352 | 394 |
353 String toString() => _i.toString(); | 395 String toString() => _i.toString(); |
354 String toHexString() => _i.toRadixString(16); | 396 String toHexString() => _i.toRadixString(16); |
355 String toRadixString(int radix) => _i.toRadixString(radix); | 397 String toRadixString(int radix) => _i.toRadixString(radix); |
356 } | 398 } |
OLD | NEW |