Skip to content

Commit

Permalink
fix(number): improve float generation for precisions of form 10^-n (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewmayer authored Dec 27, 2023
1 parent 24482a3 commit 39c715d
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 20 deletions.
7 changes: 6 additions & 1 deletion src/modules/number/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,12 @@ export class NumberModule extends SimpleModuleBase {
throw new FakerError(`Precision should be greater than 0.`);
}

const factor = 1 / precision;
const logPrecision = Math.log10(precision);
// Workaround to get integer values for the inverse of all precisions of the form 10^-n
const factor =
precision < 1 && Number.isInteger(logPrecision)
? 10 ** -logPrecision
: 1 / precision;
const int = this.int({
min: min * factor,
max: max * factor,
Expand Down
16 changes: 8 additions & 8 deletions test/modules/__snapshots__/finance.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ exports[`finance > 42 > amount > with min and max option 1`] = `"24.98"`;

exports[`finance > 42 > amount > with min option 1`] = `"380.79"`;

exports[`finance > 42 > amount > with min, leagcy max, leagcy dec and leagcy symbol 1`] = `"$24.98161"`;
exports[`finance > 42 > amount > with min, leagcy max, leagcy dec and leagcy symbol 1`] = `"$24.98160"`;

exports[`finance > 42 > amount > with min, max and dec option 1`] = `"24.98161"`;
exports[`finance > 42 > amount > with min, max and dec option 1`] = `"24.98160"`;

exports[`finance > 42 > amount > with min, max, dec and symbol option 1`] = `"#24.98161"`;
exports[`finance > 42 > amount > with min, max, dec and symbol option 1`] = `"#24.98160"`;

exports[`finance > 42 > amount > with min, max, dec, symbol and autoFormat option 1`] = `"#24.98161"`;
exports[`finance > 42 > amount > with min, max, dec, symbol and autoFormat option 1`] = `"#24.98160"`;

exports[`finance > 42 > bic > noArgs 1`] = `"UYETSCLLG53"`;

Expand Down Expand Up @@ -244,13 +244,13 @@ exports[`finance > 1337 > amount > with min and max option 1`] = `"20.48"`;

exports[`finance > 1337 > amount > with min option 1`] = `"269.40"`;

exports[`finance > 1337 > amount > with min, leagcy max, leagcy dec and leagcy symbol 1`] = `"$20.48099"`;
exports[`finance > 1337 > amount > with min, leagcy max, leagcy dec and leagcy symbol 1`] = `"$20.48098"`;

exports[`finance > 1337 > amount > with min, max and dec option 1`] = `"20.48099"`;
exports[`finance > 1337 > amount > with min, max and dec option 1`] = `"20.48098"`;

exports[`finance > 1337 > amount > with min, max, dec and symbol option 1`] = `"#20.48099"`;
exports[`finance > 1337 > amount > with min, max, dec and symbol option 1`] = `"#20.48098"`;

exports[`finance > 1337 > amount > with min, max, dec, symbol and autoFormat option 1`] = `"#20.48099"`;
exports[`finance > 1337 > amount > with min, max, dec, symbol and autoFormat option 1`] = `"#20.48098"`;

exports[`finance > 1337 > bic > noArgs 1`] = `"OEFHLYG18IL"`;

Expand Down
4 changes: 2 additions & 2 deletions test/modules/__snapshots__/location.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ exports[`location > 42 > longitude > with precision option 1`] = `-45.1655588485

exports[`location > 42 > nearbyGPSCoordinate > near origin 1`] = `
[
0.08140632875358443,
0.08140632875358447,
-0.08093642792425726,
]
`;
Expand Down Expand Up @@ -234,7 +234,7 @@ exports[`location > 1211 > longitude > with precision option 1`] = `154.26725534

exports[`location > 1211 > nearbyGPSCoordinate > near origin 1`] = `
[
-0.02872111236834616,
-0.02872111236834621,
0.05959024752564801,
]
`;
Expand Down
38 changes: 29 additions & 9 deletions test/modules/number.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest';
import { faker, FakerError, SimpleFaker } from '../../src';
import { MERSENNE_MAX_VALUE } from '../internal/mersenne-test-utils';
import { seededTests } from '../support/seeded-runs';
import { times } from './../support/times';

describe('number', () => {
seededTests(faker, 'number', (t) => {
Expand Down Expand Up @@ -259,17 +260,36 @@ describe('number', () => {
expect(results).toEqual([0, 0.4, 0.8, 1.2, 1.6]);
});

it('provides numbers with an exact precision', () => {
for (let i = 0; i < 100; i++) {
const actual = faker.number.float({
min: 0.5,
max: 0.99,
precision: 0.01,
});
expect(actual).toBe(Number(actual.toFixed(2)));
}
it('provides numbers with a given precision of 0.2', () => {
const results = [
...new Set(
Array.from({ length: 50 }, () =>
faker.number.float({
min: 0,
max: 0.4,
precision: 0.2,
})
)
),
].sort();

expect(results).toEqual([0, 0.2, 0.4]);
});

it.each(times(18))(
`provides numbers with an exact precision of 10^-%d`,
(exponent) => {
for (let i = 0; i < 100; i++) {
const actual = faker.number.float({
min: 0.5,
max: 0.99,
precision: 10 ** -exponent,
});
expect(actual).toBe(Number(actual.toFixed(exponent)));
}
}
);

it('throws an error for precision 0', () => {
expect(() => faker.number.float({ precision: 0 })).toThrow(
new FakerError('Precision should be greater than 0.')
Expand Down

0 comments on commit 39c715d

Please sign in to comment.