arc4.g in prng function sometimes returns NaN
kgh-85 opened this issue · comments
arc4.g in prng function sometimes (rare) returns NaN.
Software used: Scripting interface of Adobe After Effects 2020
For folks having the same issue:
I did this (ugly) quickfix which works:
// This function returns a random double in [0, 1) that contains
// randomness in every bit of the mantissa of the IEEE 754 value.
var prng = function() {
var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48
while (isNaN(n)) { // [KGH] Quickfix
n = arc4.g(chunks); // [KGH] Quickfix
} // [KGH] Quickfix
var d = startdenom, // and denominator d = 2 ^ 48.
x = 0; // and no 'extra last byte'.
while (n < significance) { // Fill up all significant digits by
n = (n + x) * width; // shifting numerator and
d *= width; // denominator and generating a
x = arc4.g(1); // new least-significant-byte.
while (isNaN(x)) { // [KGH] Quickfix
x = arc4.g(1); // [KGH] Quickfix
} // [KGH] Quickfix
}
while (n >= overflow) { // To avoid rounding up, before adding
n /= 2; // last byte, shift everything
d /= 2; // right using integer math until
x >>>= 1; // we have exactly the desired bits.
}
return (n + x) / d; // Form the number within [0, 1).
};
Hey.
(1) No, not tested
(2) This site says "Is based on ECMAScript 3 (1999)"
(3) Currently no time to test. Maybe later.
This is a terrifying bug. Were you able to reproduce this with any kind of seed @kgh-85?
I'm stress testing this at the moment with the following code which would allow us to reproduce any issue found:
const seedrandom = require('seedrandom');
for (let i = 0; i < 1e8; i++) {
const seed = String(Math.random());
const rng = seedrandom(seed);
console.log('trying with seed:', seed);
for (let i = 0; i < 1e8; i++) {
if (isNaN(rng.int32())) {
throw new Error('int32 NaN');
}
if (isNaN(rng.quick())) {
throw new Error('quick NaN');
}
if (isNaN(rng())) {
throw new Error('() NaN');
}
}
}
I'll report back with findings.
Hey Matt,
unfortunately not.
It was sporadic and as you can see in my quickfix I just recall the same function with the same values so I don't think it is related to the seed itself.
You should be able to reproduce it quite fast with the scripting interface of adobe after effects.
Bests
Konrad
@kgh-85 thanks for the response. The purpose of using a seed is to be able to reproduce the issue later. Using a seed shouldn't prevent this issue from happening if this issue exists. The only thing I can think of is that this is an environment issue.
After 700,000,000,000 iterations with no NaN
results using node v16.13.1
I can say that this bug doesn't exist with my environment or is astronomically improbable. cc @davidbau