Skip to content

Instantly share code, notes, and snippets.

@tkrotoff
Last active April 9, 2024 14:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkrotoff/f3f36926edeeb3f4ce4411151bde37b2 to your computer and use it in GitHub Desktop.
Save tkrotoff/f3f36926edeeb3f4ce4411151bde37b2 to your computer and use it in GitHub Desktop.
getRandomInt() & getRandomFloat()
// https://gist.github.com/tkrotoff/f3f36926edeeb3f4ce4411151bde37b2
// Exported for testing purposes only
// https://stackoverflow.com/a/45736131
export function getNumberWithDecimalPlaces(num: number, decimalPlaces: number) {
const power = 10 ** decimalPlaces;
return Math.floor(num * power) / power;
}
type GetRandomNumberOptions = {
/**
* The number of digits to appear after the decimal point.
* https://ell.stackexchange.com/q/141863
*/
decimalPlaces?: number;
};
/**
* Generates a pseudo-random float (0.3546, 5.8557...) between min (included) and max (excluded).
*/
export function getRandomFloat(min: number, max: number, options: GetRandomNumberOptions = {}) {
const { decimalPlaces } = options;
const num = Math.random() * (max - min) + min;
if (decimalPlaces === undefined) {
return num;
}
return getNumberWithDecimalPlaces(num, decimalPlaces);
}
/**
* Generates a pseudo-random integer (0, 6...) between min (included) and max (included).
*/
export function getRandomInt(min: number, max: number) {
// https://stackoverflow.com/a/7228322
return Math.floor(Math.random() * (max - min + 1)) + min;
}
import { getNumberWithDecimalPlaces, getRandomFloat, getRandomInt } from './getRandomNumber';
test('getRandomFloat()', () => {
for (let i = 0; i < 100; i++) {
expect(getRandomFloat(0, 1).toString()).toMatch(/^0\.\d+$/);
expect([0, 5e-324]).toContain(getRandomFloat(0, 5e-324 /* Number.MIN_VALUE */));
expect([0, 5e-324, 1e-323]).toContain(getRandomFloat(0, 1e-323));
expect([0, 5e-324, 1e-323, 1.5e-323, 2e-323]).toContain(getRandomFloat(0, 2e-323));
expect(getRandomFloat(0, 0)).toEqual(0);
// Min/max inverted
expect([0, 5e-324]).toContain(getRandomFloat(5e-324 /* Number.MIN_VALUE */, 0));
}
});
test('getNumberWithDecimalPlaces()', () => {
expect(getNumberWithDecimalPlaces(10.1234, 0)).toEqual(10);
expect(getNumberWithDecimalPlaces(10.1234, 1)).toEqual(10.1);
expect(getNumberWithDecimalPlaces(10.1234, 2)).toEqual(10.12);
expect(getNumberWithDecimalPlaces(10.1234, 3)).toEqual(10.123);
expect(getNumberWithDecimalPlaces(10.1234, 4)).toEqual(10.1234);
expect(getNumberWithDecimalPlaces(10.1234, 5)).toEqual(10.1234);
expect(getNumberWithDecimalPlaces(10.1234, -1)).toEqual(10);
expect(getNumberWithDecimalPlaces(10.1234, -2)).toEqual(0);
expect(getNumberWithDecimalPlaces(10.1234, -3)).toEqual(0);
});
test('getRandomFloat() with decimalPlaces', () => {
for (let i = 0; i < 100; i++) {
expect([0]).toContain(getRandomFloat(0, 1, { decimalPlaces: 0 }));
expect([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]).toContain(
getRandomFloat(0, 1, { decimalPlaces: 1 })
);
expect([0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09]).toContain(
getRandomFloat(0, 0.1, { decimalPlaces: 2 })
);
}
});
test('getRandomInt()', () => {
for (let i = 0; i < 100; i++) {
expect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).toContain(getRandomInt(0, 10));
expect([-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0]).toContain(getRandomInt(-10, 0));
expect([0, 1]).toContain(getRandomInt(0, 1));
expect([0, 1]).toContain(getRandomInt(0, 0.1)); // Yep
expect(getRandomInt(0, 0)).toEqual(0);
// Min/max inverted
expect([1, 2, 3, 4, 5, 6, 7, 8, 9]).toContain(getRandomInt(10, 0));
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment