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 // A VM patch of the dart:math library. | 5 // A VM patch of the dart:math library. |
6 patch num pow(num x, num exponent) => MathNatives.pow(x, exponent); | 6 patch num pow(num x, num exponent) { |
7 patch double atan2(num a, num b) => MathNatives.atan2(a, b); | 7 if (exponent is int) { |
8 patch double sin(num x) => MathNatives.sin(x); | 8 return x.pow(exponent); |
9 patch double cos(num x) => MathNatives.cos(x); | 9 } |
10 patch double tan(num x) => MathNatives.tan(x); | 10 // Double.pow will call exponent.toDouble(). |
11 patch double acos(num x) => MathNatives.acos(x); | 11 return x.toDouble().pow(exponent); |
12 patch double asin(num x) => MathNatives.asin(x); | 12 } |
13 patch double atan(num x) => MathNatives.atan(x); | 13 |
14 patch double sqrt(num x) => MathNatives.sqrt(x); | 14 patch double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble()); |
15 patch double exp(num x) => MathNatives.exp(x); | 15 patch double sin(num value) => _sin(value.toDouble()); |
16 patch double log(num x) => MathNatives.log(x); | 16 patch double cos(num value) => _cos(value.toDouble()); |
| 17 patch double tan(num value) => _tan(value.toDouble()); |
| 18 patch double acos(num value) => _acos(value.toDouble()); |
| 19 patch double asin(num value) => _asin(value.toDouble()); |
| 20 patch double atan(num value) => _atan(value.toDouble()); |
| 21 patch double sqrt(num value) => _sqrt(value.toDouble()); |
| 22 patch double exp(num value) => _exp(value.toDouble()); |
| 23 patch double log(num value) => _log(value.toDouble()); |
| 24 |
| 25 double _atan2(double a, double b) native "Math_atan2"; |
| 26 double _sin(double x) native "Math_sin"; |
| 27 double _cos(double x) native "Math_cos"; |
| 28 double _tan(double x) native "Math_tan"; |
| 29 double _acos(double x) native "Math_acos"; |
| 30 double _asin(double x) native "Math_asin"; |
| 31 double _atan(double x) native "Math_atan"; |
| 32 double _sqrt(double x) native "Math_sqrt"; |
| 33 double _exp(double x) native "Math_exp"; |
| 34 double _log(double x) native "Math_log"; |
17 | 35 |
18 | 36 |
19 // TODO(iposva): Handle patch methods within a patch class correctly. | 37 // TODO(iposva): Handle patch methods within a patch class correctly. |
20 patch class Random { | 38 patch class Random { |
21 | 39 |
22 /*patch*/ factory Random([int seed]) { | 40 /*patch*/ factory Random([int seed]) { |
23 if (seed == null) { | 41 if (seed == null) { |
24 seed = _Random._nextSeed(); | 42 seed = _Random._nextSeed(); |
25 } | 43 } |
26 do { | 44 do { |
27 seed = (seed + 0x5A17) & _Random._MASK_64; | 45 seed = (seed + 0x5A17) & _Random._MASK_64; |
28 } while (seed == 0); | 46 } while (seed == 0); |
29 return new _Random._internal(seed); | 47 return new _Random._internal(seed); |
30 } | 48 } |
31 } | 49 } |
32 | 50 |
33 | 51 |
34 class _Random implements Random { | 52 class _Random implements Random { |
35 // Internal state of the random number generator. | 53 // Internal state of the random number generator. |
36 var _state_lo; | 54 var _state; |
37 var _state_hi; | 55 static const kSTATE_LO = 0; |
| 56 static const kSTATE_HI = 1; |
38 | 57 |
39 _Random._internal(state) | 58 _Random._internal(state) { |
40 : _state_lo = (state & _MASK_32), _state_hi = (state >> 32); | 59 _state = new List(2); |
| 60 _state[kSTATE_LO] = state & _MASK_32; |
| 61 _state[kSTATE_HI] = state >> 32; |
| 62 } |
41 | 63 |
42 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. | 64 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. |
43 // http://en.wikipedia.org/wiki/Multiply-with-carry | 65 // http://en.wikipedia.org/wiki/Multiply-with-carry |
44 // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1. | 66 // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1. |
45 int _nextInt32() { | 67 int _nextInt32() { |
46 var state = ((_A * (_state_lo)) + _state_hi) & _MASK_64; | 68 var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64; |
47 _state_lo = state & _MASK_32; | 69 _state[kSTATE_LO] = state & _MASK_32; |
48 _state_hi = state >> 32; | 70 _state[kSTATE_HI] = state >> 32; |
49 return _state_lo; | 71 return _state[kSTATE_LO]; |
50 } | 72 } |
51 | 73 |
52 int nextInt(int max) { | 74 int nextInt(int max) { |
53 if (max <= 0 || max > _POW2_32) { | 75 if (max <= 0 || max > _POW2_32) { |
54 throw new ArgumentError("max must be positive and < 2^32:" | 76 throw new ArgumentError("max must be positive and < 2^32:" |
55 " $max"); | 77 " $max"); |
56 } | 78 } |
57 if ((max & -max) == max) { | 79 if ((max & -max) == max) { |
58 // Fast case for powers of two. | 80 // Fast case for powers of two. |
59 return _nextInt32() & (max - 1); | 81 return _nextInt32() & (max - 1); |
(...skipping 29 matching lines...) Expand all Loading... |
89 | 111 |
90 static int _nextSeed() { | 112 static int _nextSeed() { |
91 if (_prng == null) { | 113 if (_prng == null) { |
92 // TODO(iposva): Use system to get a random seed. | 114 // TODO(iposva): Use system to get a random seed. |
93 _prng = new Random(new Date.now().millisecondsSinceEpoch); | 115 _prng = new Random(new Date.now().millisecondsSinceEpoch); |
94 } | 116 } |
95 // Trigger the PRNG once to change the internal state. | 117 // Trigger the PRNG once to change the internal state. |
96 return _prng._nextInt32(); | 118 return _prng._nextInt32(); |
97 } | 119 } |
98 } | 120 } |
OLD | NEW |