Skip to content

Non-uniform distribution of randNumber generation #362

@Malien

Description

@Malien

Is this a regression?

No

Description

Given the following snippet

import { randNumber } from "@ngneat/falso"

const freq = Array(10).fill(0)
for (const n of randNumber({ min: 0, max: 9, length: 10_000 }) {
  freq[n]++
}

we can see that the distribution is almost uniform (sample output; run-to-run variance is negligible):

[563, 1041, 1123, 1062, 1069, 1171, 1171, 1113, 1109, 578]

First and last entries are always encountered half as much. No matter, if the number is an integer, a float (via setting fraction parameter), and does not depend on the range size (min and max parameters), probabilities converge to
$$\left[\frac 1 {2 \cdot (S - 1) }, \frac 1 {S - 1}, \cdots, \frac 1 {S-1}, \frac 1 {2\cdot(S-1)} \right]$$
for a given amount of discrete values (S) with greater number of tests.

It is non-intuitive. This looks like a bug, in otherwise uniform-ish distribution.

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

No response

Please provide the environment you discovered this bug in

No response

Anything else?

Changing the algo will impact current "hard-seeded" outcomes, as such this might be a breaking change. I'm not saying that this is an important issue, just something I've noted. There are workarounds, such as using built-in (non-seedable) Math.random, using another lib, or using randNumber adding one more discrete value, and collapsing first and last outcomes into one.

Do you want to create a pull request?

No

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions