Skip to content

Commit

Permalink
⚡️ Drop infinite loop for explicit loop (#507)
Browse files Browse the repository at this point in the history
  • Loading branch information
dubzzz authored Jan 8, 2023
1 parent 2dd7280 commit bb69be5
Showing 1 changed file with 21 additions and 17 deletions.
38 changes: 21 additions & 17 deletions src/distribution/internals/UnsafeUniformIntDistributionInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ export function unsafeUniformIntDistributionInternal(rangeSize: number, rng: Ran
// Range provided by the RandomGenerator is large enough
if (rangeSize <= NumValues) {
const MaxAllowed = NumValues - (NumValues % rangeSize);
while (true) {
const out = rng.unsafeNext();
const deltaV = out - MinRng;
if (deltaV < MaxAllowed) {
return deltaV % rangeSize; // Warning: we expect NumValues <= 2**32, so diff too
}
let deltaV = rng.unsafeNext() - MinRng;
while (deltaV >= MaxAllowed) {
deltaV = rng.unsafeNext() - MinRng;
}
return deltaV % rangeSize; // Warning: we expect NumValues <= 2**32, so diff too
}

// Compute number of iterations required to have enough random
Expand All @@ -30,16 +28,22 @@ export function unsafeUniformIntDistributionInternal(rangeSize: number, rng: Ran
}
const MaxAcceptedRandom = rangeSize * Math.floor((1 * FinalNumValues) / rangeSize);

while (true) {
// Aggregate mutiple calls to next() into a single random value
let value = 0;
for (let num = 0; num !== NumIterations; ++num) {
const out = rng.unsafeNext();
value = NumValues * value + (out - MinRng); // Warning: we overflow may when diff > max_safe (eg: =max_safe-min_safe+1)
}
if (value < MaxAcceptedRandom) {
const inDiff = value - rangeSize * Math.floor((1 * value) / rangeSize);
return inDiff;
}
let largeDeltaV = unsafeComputeValue(rng, NumIterations, NumValues, MinRng);
while (largeDeltaV >= MaxAcceptedRandom) {
largeDeltaV = unsafeComputeValue(rng, NumIterations, NumValues, MinRng);
}
const inDiff = largeDeltaV - rangeSize * Math.floor((1 * largeDeltaV) / rangeSize);
return inDiff;
}

/**
* Aggregate multiple calls to next() into a single random value
*/
function unsafeComputeValue(rng: RandomGenerator, NumIterations: number, NumValues: number, MinRng: number): number {
let value = 0;
for (let num = 0; num !== NumIterations; ++num) {
const out = rng.unsafeNext();
value = NumValues * value + (out - MinRng); // Warning: we overflow may when diff > max_safe (eg: =max_safe-min_safe+1)
}
return value;
}

0 comments on commit bb69be5

Please sign in to comment.