Skip to content

Commit 39c715d

Browse files
authored
fix(number): improve float generation for precisions of form 10^-n (#2581)
1 parent 24482a3 commit 39c715d

File tree

4 files changed

+45
-20
lines changed

4 files changed

+45
-20
lines changed

src/modules/number/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,12 @@ export class NumberModule extends SimpleModuleBase {
150150
throw new FakerError(`Precision should be greater than 0.`);
151151
}
152152

153-
const factor = 1 / precision;
153+
const logPrecision = Math.log10(precision);
154+
// Workaround to get integer values for the inverse of all precisions of the form 10^-n
155+
const factor =
156+
precision < 1 && Number.isInteger(logPrecision)
157+
? 10 ** -logPrecision
158+
: 1 / precision;
154159
const int = this.int({
155160
min: min * factor,
156161
max: max * factor,

test/modules/__snapshots__/finance.spec.ts.snap

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ exports[`finance > 42 > amount > with min and max option 1`] = `"24.98"`;
2424

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

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

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

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

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

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

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

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

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

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

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

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

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

test/modules/__snapshots__/location.spec.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ exports[`location > 42 > longitude > with precision option 1`] = `-45.1655588485
7474

7575
exports[`location > 42 > nearbyGPSCoordinate > near origin 1`] = `
7676
[
77-
0.08140632875358443,
77+
0.08140632875358447,
7878
-0.08093642792425726,
7979
]
8080
`;
@@ -234,7 +234,7 @@ exports[`location > 1211 > longitude > with precision option 1`] = `154.26725534
234234

235235
exports[`location > 1211 > nearbyGPSCoordinate > near origin 1`] = `
236236
[
237-
-0.02872111236834616,
237+
-0.02872111236834621,
238238
0.05959024752564801,
239239
]
240240
`;

test/modules/number.spec.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest';
33
import { faker, FakerError, SimpleFaker } from '../../src';
44
import { MERSENNE_MAX_VALUE } from '../internal/mersenne-test-utils';
55
import { seededTests } from '../support/seeded-runs';
6+
import { times } from './../support/times';
67

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

262-
it('provides numbers with an exact precision', () => {
263-
for (let i = 0; i < 100; i++) {
264-
const actual = faker.number.float({
265-
min: 0.5,
266-
max: 0.99,
267-
precision: 0.01,
268-
});
269-
expect(actual).toBe(Number(actual.toFixed(2)));
270-
}
263+
it('provides numbers with a given precision of 0.2', () => {
264+
const results = [
265+
...new Set(
266+
Array.from({ length: 50 }, () =>
267+
faker.number.float({
268+
min: 0,
269+
max: 0.4,
270+
precision: 0.2,
271+
})
272+
)
273+
),
274+
].sort();
275+
276+
expect(results).toEqual([0, 0.2, 0.4]);
271277
});
272278

279+
it.each(times(18))(
280+
`provides numbers with an exact precision of 10^-%d`,
281+
(exponent) => {
282+
for (let i = 0; i < 100; i++) {
283+
const actual = faker.number.float({
284+
min: 0.5,
285+
max: 0.99,
286+
precision: 10 ** -exponent,
287+
});
288+
expect(actual).toBe(Number(actual.toFixed(exponent)));
289+
}
290+
}
291+
);
292+
273293
it('throws an error for precision 0', () => {
274294
expect(() => faker.number.float({ precision: 0 })).toThrow(
275295
new FakerError('Precision should be greater than 0.')

0 commit comments

Comments
 (0)