简体   繁体   English

随机获取<u64> Integer 在 AssemblyScript 中</u64>

[英]Obtaining a random <u64> Integer in AssemblyScript

In the AsemblyScript book it mentions that Math.random() takes a seed and returns an <f64> value.AsemblyScript 书中,它提到Math.random()接受一个种子并返回一个<f64>值。 I just need a random <u64> value.我只需要一个随机的<u64>值。 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.或者用f64.MAX_VALUE代替0xffffffffffffffff等等。

but I keep getting 0.但我一直得到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.我可以很好地获得<U32>随机值,但是当我将两个<U32>随机值相乘时,我得到 52 个随机位,而 rest 为 0。我理解为什么这发生在我的 JS 背景下,仍然来自类型结构和较低级别AS 的抽象我希望没有摩擦。

How exactly I can obtain a <u64> random integer properly with AssemblyScript?我如何才能使用 AssemblyScript 正确地获得一个<u64>随机 integer?

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.阅读您的问题后,我决定研究一下 AssemblyScript 如何在标准库中实现Math.random ,看看我是否能从中得到一些启发来解决您的问题。

Funny, enough, it seems to use the murmurhash3 and some custom extra hashes.有趣的是,它似乎使用了murmurhash3和一些自定义的额外哈希值。 Right before the return, it reinterprets a u64 value into a f64 , after some extra processing:就在返回之前,经过一些额外处理后,它将u64值重新解释为f64

    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:我很好奇我们是否可以将该u64值直接用作随机序列中的数字,所以我重新处理了涉及的位并将其发布在 github此处,但主要的 function 是:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM