TinyChan

New reply in topic: Random discussions thread

You are not recognized as the original poster of this topic.

:

You are required to fill in a captcha for your first 5 posts. Sorry, but this is required to stop people from posting while drunk. Please be responsible and don't drink and post!
If you receive this often, consider not clearing your cookies.

Please familiarise yourself with the rules and markup syntax before posting.


Replying to Phoneposter…

/*
I need a pseudo-random number generator in JavaScript that:
  • Is deterministic and seed-based.
  • Responds sensitively to small changes in the seed.
  • Produces uniformly distributed numbers in [0, 1) with good statistical properties.
To ensure the generator's uniformity and randomness, you should perform statistical tests like the Kolmogorov-Smirnov test to compare the distribution of generated numbers to a uniform distribution.

To OpenAI o1: “Write a uniformly-distributed double floating-point pseudo-random generator within the range [0,1) that has a (double floating-point) seed as its parameter, always returning the same value when passing in the same seed, but exhibits drastic changes even when a single mantissa bit of the seed has been altered, using 64-bit IEEE 754 double values and `var float=new Float64Array(1),bytes=new Uint8Array(float.buffer);float[0]=value;` to manipulate double-value bits in JavaScript. Use statistical tests to evaluate its uniformity, bit-level analysis, and periodicity check to prevent repetition.”
*/
function getRandomFromSeed(seed){
    //Initialize typed arrays for bit manipulation
    var float=new Float64Array(1),
        bytes=new Uint8Array(float.buffer); //8 bytes to represent 64 bits
    float[0]=seed;
    //Convert the seed's bits into a BigInt
    var seedBigInt=0n;
    for(let i=0;i<8;i++)
        seedBigInt|=BigInt(bytes[i])<<BigInt(8*i);
    //Apply the SplitMix64 algorithm
    var x=(seedBigInt+0x9E3779B97F4A7C15n)&0xFFFFFFFFFFFFFFFFn,
        z=x;
    z=((z^(z>>30n))*0xBF58476D1CE4E5B9n)&0xFFFFFFFFFFFFFFFFn;
    z=((z^(z>>27n))*0x94D049BB133111EBn)&0xFFFFFFFFFFFFFFFFn;
    z^=z>>31n;
    //Extract the upper 53 bits to fit into a double's mantissa
    var result_bits=z>>11n;
    //Construct a double in the range [1, 2)
    var sign_bit=0n,
        //exponent_bits=0x3FEn, //Exponent for 2^-1 (since bias is 1023), it gives [-.5,0) though
        exponent_bits=0x3FFn, //Exponent for 2^0 (since bias is 1023)
        fraction_bits=result_bits&0xFFFFFFFFFFFFFn, //Lower 52 bits
        //Combine the sign, exponent, and fraction bits
        double_bits=(sign_bit<<63n)|(exponent_bits<<52n)|fraction_bits;
    //Write the bits back into the float's bytes
    for(let i=0;i<8;i++)
        bytes[i]=Number((double_bits>>BigInt(8*i))&0xFFn);
    //Subtract 1 to get a value in [0, 1)
    return float[0]-1;
}

var minimumValue= Infinity,
    maximumValue=-Infinity,
    currentSeed=0,
    values=[],maxLength=1000;
function setup(){createCanvas(windowWidth,windowHeight);}
function draw(){
    background(0);
    var currentValue=getRandomFromSeed(currentSeed);
    values.push(currentValue);
    if(values.length>=maxLength)values.shift();
    minimumValue=Math.min(minimumValue,currentValue);
    maximumValue=Math.max(maximumValue,currentValue);
    var gX=16,gY=16,gW=width-(16*2),gH=300;
    noFill();stroke(200);rect(gX,gY,gW,gH);
    stroke(255,0,0);line(gX,gY+(1-minimumValue)*gH,gX+gW,gY+(1-minimumValue)*gH);
    stroke(0,255,0);line(gX,gY+(1-maximumValue)*gH,gX+gW,gY+(1-maximumValue)*gH);
    stroke(255);
    for(let i=0;i<values.length-1;i++)
        line(gX+(i    /maxLength)*gW,
             gY+(1-values[i]  )*gH,
             gX+((i+1)/maxLength)*gW,
             gY+(1-values[i+1])*gH);
    noStroke();fill(255);textAlign(LEFT,TOP);
    text(`Min: ${minimumValue}\nMax: ${maximumValue}\nValue: ${currentValue}\nCurrent: ${currentValue>=0&&currentValue<1?"Within range":"Outside of range"}`,gX,gY+gH+16);
    currentSeed+=.001;
}