<u64> 在组装脚本中获取随机整数



在assemblyscript书中提到Math.random()接受一个种子并返回一个<f64>值。我只需要一个随机的<u64>值。我该怎么做呢?

我试着

(Math.random() * 0xffffffffffffffff) as u64
<u64>(<f64>Math.random() * <f64>0xffffffffffffffff)
(<f64>Math.random() * <f64>0xffffffffffffffff) as u64

或者用f64.MAX_VALUE代替0xffffffffffffffff

但是我一直得到0

我可以得到<U32>随机值,但是当我乘以两个<U32>随机值时,我得到52个随机比特,其余的是0。我理解为什么会发生这种情况,从我的JS背景,仍然从类型化结构和AS的低级抽象,我希望得到没有摩擦。

如何准确地我可以获得<u64>随机整数正确与AssemblyScript?

编辑:

我想我终于把它弄得像

(<u64>(Math.random() * u32.MAX_VALUE) << 32) | <u32>(Math.random() * u32.MAX_VALUE)

但这真的应该这样做吗?

读完你的问题后,我决定研究一下AssemblyScript如何在标准库中实现Math.random,看看我是否能得到一些灵感来解决你的问题。

有趣的是,它似乎使用了murmurhash3和一些自定义的额外哈希。在返回之前,经过一些额外的处理,它将u64值重新解释为f64:
let r = (s0 >> 12) | 0x3FF0000000000000;
return reinterpret<f64>(r) - 1;

我很好奇我们是否可以直接使用u64值作为随机序列中的数字,所以我重新设计了所涉及的比特并将其发布在github上,但主要功能是:

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;
}

一个非常简单的测试表明,至少乍一看,它产生了相当好的随机结果:

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
}

相关内容

  • 没有找到相关文章

最新更新