如何让这个 PRNG 生成范围内的数字?

How to get this PRNG to generate numbers within the range?(如何让这个 PRNG 生成范围内的数字?)

本文介绍了如何让这个 PRNG 生成范围内的数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现 这个 我在下面做了这个,用于 JavaScript 中的 8 位和 16 位数字:

I found this which I made into this below, for 8 and 16 bit numbers in JavaScript:

const fetch = (x, o) => {
  if (x >= o) {
    return x
  } else {
    const v = (x * x) % o
    return (x <= o / 2) ? v : o - v
  }
}

const fetch16 = (x) => fetch(x, 65519)
const fetch8 = (x) => fetch(x, 251)

// the last number can be anything.
const build16 = (x, o) => fetch16((fetch16(x) + o) ^ 42703)
const build8 = (x, o) => fetch8((fetch8(x) + o) ^ 101)

let i = 0
let invalid = []
while (i < 255) {
  let j = 0
  while (j < 255) {
    let x = build8(i, j)
    if (x > 255) {
      invalid.push([ i, j, x ])
    }
    j++
  }
  i++
}

console.log(JSON.stringify(invalid))

然而,虽然 fetch8fetch16 函数在重复之前循环遍历整个数字集,但 build8build16 函数没有,它们超出了所需的范围,请参阅上述代码的输出.例如,当i = 11j = 184时,x = 340,即>;255.

However, while the fetch8 and fetch16 functions properly cycle through the entire set of numbers before repeating, the build8 and build16 functions don't, they go outside of the desired range, see the output from the above code. For example, when i = 11 and j = 184, x = 340, which is > 255.

但是,这些 build8build16 函数的输出非常棒.它看起来完全是随机的,并且在遍历整个集合之前不会重复任何值.

However, the output from these build8 and build16 functions is fantastic. It appears entirely random and doesn't repeat any values before going through the whole set.

如何修改这些 build8build16 函数,使它们仅包含集合中的数字(0-255 或 0-65535),但看起来完全随机就像他们在这里做的那样,但在遍历所有值之前从不重复一个值?

How can I modify these build8 and build16 functions so that they only include numbers within the set (0-255, or 0-65535), yet appear entirely random like they do here, and yet never repeat a value before going through all of them?

我不完全确定帖子的作者是如何登陆 fetch8((fetch8(x) + o) ^ 101) 的,例如,执行 XOR 并传入这样的值.但最终结果显得非常随机.我只是想这样做,所以输出是:

I'm not entirely sure how the author of the post landed on fetch8((fetch8(x) + o) ^ 101) for example, doing that XOR and passing in values like this. But the end result appears very random. I just would like to make it so the output is:

  • 在所需的值范围内.
  • 在枚举完所有值之前不重复任何值.
  • 看起来像 build8 一样完全随机.

推荐答案

你得到超出范围值的原因是虽然 fetchXX 会产生一个范围内的值,但 + o 破坏了这个属性.XOR 操作可能有时会将其带回范围内,但并非总是如此.

The reason you get out of range values is that although fetchXX will produce a value in range, the + o spoils this property. The XOR operation may sometimes bring it back in range, but not always.

所以你应该取 + o 之后的值的模.XOR 操作永远不会使其超出范围,因此可以保持原样.

So you should take the modulo of the value after + o. The XOR operation will never bring it out of range, so that can stay as it is.

其次,要测试是否没有生成重复项,您需要修复传递给 buildXX 函数的两个参数之一,只改变另一个.冻结第二个论点对我来说似乎更合乎逻辑.

Secondly, to test whether no duplicates are generated, you would need to fix one of the two arguments passed to the buildXX function and only vary the other. It seems more logical to me to freeze the second argument.

这就是它的样子:

const fetch = (x, o) => {
  if (x >= o) {
    return x
  } else {
    const v = (x * x) % o
    return (x <= o / 2) ? v : o - v
  }
}

const fetch16 = (x) => fetch(x, 65519)
const fetch8 = (x) => fetch(x, 251)

// the last number can be anything.
const build16 = (x, o) => fetch16((fetch16(x) + o) % 65536 ^ 42703)
const build8 = (x, o) => fetch8((fetch8(x) + o) % 256 ^ 101)

const j = 115; // If you don't want duplicates, either i or j should stay fixed
let i = 0
let invalid = [];
let valid = new Set;
while (i <= 255) { // <-- small fix here!
    let x = build8(i, j); // To test, you can swap i and j here, and run again.
    if (x > 255) {
        invalid.push([ i, j, x ]);
    } else {
        valid.add(x);
    }
    i++;
}

console.log("invalid:", JSON.stringify(invalid));
console.log("count of valid:", valid.size);

这篇关于如何让这个 PRNG 生成范围内的数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何让这个 PRNG 生成范围内的数字?

基础教程推荐