如何让这个 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))
然而,虽然 fetch8
和 fetch16
函数在重复之前循环遍历整个数字集,但 build8
和 build16
函数没有,它们超出了所需的范围,请参阅上述代码的输出.例如,当i = 11
和j = 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
.
但是,这些 build8
和 build16
函数的输出非常棒.它看起来完全是随机的,并且在遍历整个集合之前不会重复任何值.
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.
如何修改这些 build8
和 build16
函数,使它们仅包含集合中的数字(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);
相关文章