In the AsemblyScript book it mentions that Math.random()
takes a seed and returns an <f64>
value. I just need a random <u64>
value. How do I achive that?
I tried
(Math.random() * 0xffffffffffffffff) as u64
<u64>(<f64>Math.random() * <f64>0xffffffffffffffff)
(<f64>Math.random() * <f64>0xffffffffffffffff) as u64
or with f64.MAX_VALUE
in the place of 0xffffffffffffffff
and whatnot.
but I keep getting 0.
I can get <U32>
random values just fine but When I multiply two <U32>
random values I get like 52 random bits and the rest is 0. I understand why this happens from my JS background, still from the typed struct and lower level abstractions of AS I hoped to get no friction.
How exactly I can obtain a <u64>
random integer properly with AssemblyScript?
Edit:
I think I finally got it doing like
(<u64>(Math.random() * u32.MAX_VALUE) << 32) | <u32>(Math.random() * u32.MAX_VALUE)
but is this really how it should be done?
After reading your question, I decided to look into how AssemblyScript implements Math.random
in the standard library, to see if I can get some inspiration to solve your problem.
Funny, enough, it seems to use the murmurhash3
and some custom extra hashes. Right before the return, it reinterprets a u64
value into a f64
, after some extra processing:
let r = (s0 >> 12) | 0x3FF0000000000000;
return reinterpret<f64>(r) - 1;
I got curious if we can use that u64
value directly as a number in a random sequence, so I reworked the bits involved and posted it on github here, but the main function is:
export function randomU64(): u64 { // see: v8/src/base/utils/random-number-generator.cc
if (!random_seeded) seedRandom(reinterpret<i64>(0)); // TODO: for now, the seed is always 0.
let s1 = random_state0_64;
let s0 = random_state1_64;
random_state0_64 = s0;
s1 ^= s1 << 23;
s1 ^= s1 >> 17;
s1 ^= s0;
s1 ^= s0 >> 26;
random_state1_64 = s1;
return s0;
}
A very brief test shows that, at least at a glance, it produces fairly good random results:
Test randomU64 distribution. All values should be fairly close.
Map(19) {
0n => 987,
1n => 495, -1n => 515, 2n => 542, -2n => 489,
3n => 518, -3n => 495, 4n => 479, -4n => 510,
5n => 513, -5n => 497, 6n => 473, -6n => 505,
7n => 468, -7n => 528, 8n => 501, -8n => 472,
9n => 519, -9n => 494
}