aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShinigami <[email protected]>2022-10-30 09:03:26 +0100
committerGitHub <[email protected]>2022-10-30 08:03:26 +0000
commit9abfcfb90cc73bfe961d446f5fb950976d5c2ccd (patch)
tree1e76203a6cfd8bb6c2b83734fee4cebf56db5072 /src
parent4da3d5eac3805f609f4e40385aee6a645fd93540 (diff)
downloadfaker-9abfcfb90cc73bfe961d446f5fb950976d5c2ccd.tar.xz
faker-9abfcfb90cc73bfe961d446f5fb950976d5c2ccd.zip
refactor(mersenne): rewrite internal mersenne (#1447)
Diffstat (limited to 'src')
-rw-r--r--src/faker.ts11
-rw-r--r--src/internal/mersenne/mersenne.ts96
-rw-r--r--src/modules/datatype/index.ts11
3 files changed, 42 insertions, 76 deletions
diff --git a/src/faker.ts b/src/faker.ts
index f8a46511..fd7ed522 100644
--- a/src/faker.ts
+++ b/src/faker.ts
@@ -1,7 +1,8 @@
import type { LocaleDefinition } from './definitions';
import { FakerError } from './errors/faker-error';
import { deprecated } from './internal/deprecated';
-import { MersenneModule } from './internal/mersenne/mersenne';
+import type { Mersenne } from './internal/mersenne/mersenne';
+import mersenne from './internal/mersenne/mersenne';
import type { KnownLocale } from './locales';
import { AnimalModule } from './modules/animal';
import { ColorModule } from './modules/color';
@@ -79,7 +80,7 @@ export class Faker {
readonly definitions: LocaleDefinition = this.initDefinitions();
/** @internal */
- private readonly _mersenne: MersenneModule = new MersenneModule();
+ private readonly _mersenne: Mersenne = mersenne();
readonly random: RandomModule = new RandomModule(this);
@@ -286,11 +287,7 @@ export class Faker {
seed(
seed: number | number[] = Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER)
): number | number[] {
- if (Array.isArray(seed) && seed.length) {
- this._mersenne.seed_array(seed);
- } else if (!Array.isArray(seed) && !isNaN(seed)) {
- this._mersenne.seed(seed);
- }
+ this._mersenne.seed(seed);
return seed;
}
diff --git a/src/internal/mersenne/mersenne.ts b/src/internal/mersenne/mersenne.ts
index 16019e29..e7c0355c 100644
--- a/src/internal/mersenne/mersenne.ts
+++ b/src/internal/mersenne/mersenne.ts
@@ -1,81 +1,49 @@
-import { FakerError } from '../../errors/faker-error';
-import Gen from './twister';
+import Twister from './twister';
/**
- * Module to generate seed based random numbers.
+ * Generate seed based random numbers.
*
* @internal
*/
-export class MersenneModule {
- private gen = new Gen();
-
- constructor() {
- this.gen.initGenrand(Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER));
-
- // Bind `this` so namespaced is working correctly
- for (const name of Object.getOwnPropertyNames(MersenneModule.prototype)) {
- if (name === 'constructor' || typeof this[name] !== 'function') {
- continue;
- }
- this[name] = this[name].bind(this);
- }
- }
-
+export interface Mersenne {
/**
- * Generates a random number between `[min, max)`.
- *
- * @param max The maximum number. Defaults to `32768`.
- * @param min The minimum number. Defaults to `0`.
+ * Generates a random number between `[min, max)`. The result is already floored.
*
- * @example
- * faker.mersenne.rand() // 15515
- * faker.mersenne.rand(1000, 500) // 578
- *
- * @since 5.5.0
+ * @param options The options to generate a random number.
+ * @param options.min The minimum number.
+ * @param options.max The maximum number.
*/
- rand(max = 32768, min = 0): number {
- if (min > max) {
- const temp = min;
- min = max;
- max = temp;
- }
-
- return Math.floor(this.gen.genrandReal2() * (max - min) + min);
- }
+ next(options: { max: number; min: number }): number;
/**
* Sets the seed to use.
*
- * @param S The seed to use.
- * @throws If the seed is not a `number`.
- *
- * @since 5.5.0
+ * @param seed The seed to use.
*/
- seed(S: number): void {
- if (typeof S !== 'number') {
- throw new FakerError(
- `seed(S) must take numeric argument; is ${typeof S}`
- );
- }
+ seed(seed: number | number[]): void;
+}
+
+/**
+ * Generate seed based random numbers.
+ *
+ * @internal
+ */
+export default function mersenne(): Mersenne {
+ const twister = new Twister();
- this.gen.initGenrand(S);
- }
+ twister.initGenrand(Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER));
- /**
- * Sets the seed to use.
- *
- * @param A The seed to use.
- * @throws If the seed is not a `number[]`.
- *
- * @since 5.5.0
- */
- seed_array(A: number[]): void {
- if (typeof A !== 'object') {
- throw new FakerError(
- `seed_array(A) must take array of numbers; is ${typeof A}`
- );
- }
+ return {
+ next({ min, max }): number {
+ return Math.floor(twister.genrandReal2() * (max - min) + min);
+ },
- this.gen.initByArray(A, A.length);
- }
+ seed(seed: number | number[]): void {
+ if (typeof seed === 'number') {
+ twister.initGenrand(seed);
+ } else if (Array.isArray(seed)) {
+ twister.initByArray(seed, seed.length);
+ }
+ },
+ };
}
diff --git a/src/modules/datatype/index.ts b/src/modules/datatype/index.ts
index 41c5c3e4..d4fcbbd6 100644
--- a/src/modules/datatype/index.ts
+++ b/src/modules/datatype/index.ts
@@ -1,7 +1,7 @@
import type { Faker } from '../..';
import { FakerError } from '../../errors/faker-error';
import { deprecated } from '../../internal/deprecated';
-import type { MersenneModule } from '../../internal/mersenne/mersenne';
+import type { Mersenne } from '../../internal/mersenne/mersenne';
/**
* Module to generate various primitive values and data types.
@@ -56,13 +56,14 @@ export class DatatypeModule {
throw new FakerError(`Max ${max} should be greater than min ${min}.`);
}
- const mersenne: MersenneModule =
+ const mersenne: Mersenne =
// @ts-expect-error: access private member field
this.faker._mersenne;
- const randomNumber = Math.floor(
- mersenne.rand(max / precision + 1, min / precision)
- );
+ const randomNumber = mersenne.next({
+ min: min / precision,
+ max: max / precision + 1,
+ });
// Workaround problem in float point arithmetics for e.g. 6681493 / 0.01
return randomNumber / (1 / precision);