davidbau / seedrandom

seeded random number generator for Javascript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.

commented

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

commented

@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