Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Unified Diff: sdk/lib/_internal/lib/math_patch.dart

Issue 156533002: Add more complex mixing of random seed. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/lib/math.cc ('k') | tests/lib/math/random_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/lib/math_patch.dart
diff --git a/sdk/lib/_internal/lib/math_patch.dart b/sdk/lib/_internal/lib/math_patch.dart
index e3aabe3d4265451d9d114742159a247e6342fe9e..2ba47aa4846611159d03037c8d42afdf87c4e804 100644
--- a/sdk/lib/_internal/lib/math_patch.dart
+++ b/sdk/lib/_internal/lib/math_patch.dart
@@ -80,23 +80,81 @@ class _Random implements Random {
static const int _MASK32 = 0xFFFFFFFF;
// State comprised of two unsigned 32 bit integers.
- int _lo;
- int _hi;
+ int _lo = 0;
+ int _hi = 0;
// Implements:
+ // uint64_t hash = 0;
// do {
- // seed = (seed + 0x5A17) & _Random._MASK_64;
- // } while (seed == 0);
- // _lo = seed & _MASK_32;
- // _hi = seed >> 32;
+ // hash = hash * 1037 ^ mix64((uint64_t)seed);
+ // seed >>= 64;
+ // } while (seed != 0 && seed != -1); // Limits for pos/neg seed.
+ // if (hash == 0) {
+ // hash = 0x5A17;
+ // }
+ // _lo = hash & _MASK_32;
+ // _hi = hash >> 32;
// and then does four _nextState calls to shuffle bits around.
_Random(int seed) {
- // Works the same as the VM version for positive integers up to 2^53.
- // For bigints, the VM always uses zero as seed. That is really a bug, and
- // we don't simulate that.
- seed += 0x5A17;
- _lo = seed & _MASK32;
- _hi = (seed - _lo) ~/ _POW2_32;
+ int empty_seed = 0;
+ if (seed < 0) {
+ empty_seed = -1;
+ }
+ do {
+ int low = seed & _MASK32;
+ seed = (seed - low) ~/ _POW2_32;
+ int high = seed & _MASK32;
+ seed = (seed - high) ~/ _POW2_32;
+
+ // Thomas Wang's 64-bit mix function.
+ // http://www.concentric.net/~Ttwang/tech/inthash.htm
+ // via. http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
+
+ // key = ~key + (key << 21);
+ int tmplow = low << 21;
+ int tmphigh = (high << 21) | (low >> 11);
+ tmplow = (~low & _MASK32) + tmplow;
+ low = tmplow & _MASK32;
+ high = (~high + tmphigh + ((tmplow - low) ~/ 0x100000000)) & _MASK32;
+ // key = key ^ (key >> 24).
+ tmphigh = high >> 24;
+ tmplow = (low >> 24) | (high << 8);
+ low ^= tmplow;
+ high ^= tmphigh;
+ // key = key * 265
+ tmplow = low * 265;
+ low = tmplow & _MASK32;
+ high = (high * 265 + (tmplow - low) ~/ 0x100000000) & _MASK32;
+ // key = key ^ (key >> 14);
+ tmphigh = high >> 14;
+ tmplow = (low >> 14) | (high << 18);
+ low ^= tmplow;
+ high ^= tmphigh;
+ // key = key * 21
+ tmplow = low * 21;
+ low = tmplow & _MASK32;
+ high = (high * 21 + (tmplow - low) ~/ 0x100000000) & _MASK32;
+ // key = key ^ (key >> 28).
+ tmphigh = high >> 28;
+ tmplow = (low >> 28) | (high << 4);
+ low ^= tmplow;
+ high ^= tmphigh;
+ // key = key + (key << 31);
+ tmplow = low << 31;
+ tmphigh = (high << 31) | (low >> 1);
+ tmplow += low;
+ low = tmplow & _MASK32;
+ high = (high + tmphigh + (tmplow - low) ~/ 0x100000000) & _MASK32;
+ // Mix end.
+
+ // seed = seed * 1037 ^ key;
+ tmplow = _lo * 1037;
+ _lo = tmplow & _MASK32;
+ _hi = (_hi * 1037 + (tmplow - _lo) ~/ 0x100000000) & _MASK32;
+ _lo ^= low;
+ _hi ^= high;
+ } while (seed != empty_seed);
+
if (_hi == 0 && _lo == 0) {
_lo = 0x5A17;
}
« no previous file with comments | « runtime/lib/math.cc ('k') | tests/lib/math/random_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698