Repository navigation
fix(number): avoid rounding past inclusive upper bounds - #4145
Conversation
✅ Deploy Preview for fakerjs ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## next #4145 +/- ##
=======================================
Coverage 99.18% 99.18%
=======================================
Files 1178 1178
Lines 3940 3940
Branches 697 711 +14
=======================================
Hits 3908 3908
Misses 28 28
Partials 4 4
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Nicely spotted. ❤️
FFR:
1 - Number.EPSILON / 2 // 0.9999999999999999 // 1 - 2^-53
1 - Number.EPSILON // 0.9999999999999998Reproduction code:
await enableFaker();
faker.number.int({ min: 1, max: 2, distributor: () => 1 - Number.EPSILON / 2 }); // Previously 3, now 2
faker.number.int({ min: 1, max: 2, distributor: () => 1 - Number.EPSILON }); // 2 as before
faker.number.int({ min: 1, max: 3, distributor: () => 1 - Number.EPSILON / 2 }); // 3 as beforeI was unable to find other edge cases for this, as this only seems to affect max - min = 1 cases and randomizer.next() = MAX and min != 0.
|
@shin4141 Can you please address the above comments? |
|
Thanks for the pointers. I updated With the pre-fix |
ST-DDT
left a comment
There was a problem hiding this comment.
Your comment above sounds a bit AI-ish.
Please trim it down to only relevant information.
Or: Dont force us to read something, you didnt bother writing.
Summary
number.int()can exceed its inclusivemaxwhen adding a nonzero lower bound rounds the intermediate floating-point value up beforeMath.floorruns. For example,faker.number.int({ min: 1, max: 2, distributor: () => 1 - Number.EPSILON / 2 })returns3onnextbefore this change.Flooring the scaled distributor result before adding the integer lower bound avoids that intermediate rounding.
number.float()withmultipleOfuses the same integer path, so it benefits from the fix as well. The change is one runtime line and two regression tests; it does not change the public API.Tests
nextimplementation (3instead of2, and1.5instead of1).test/modules/number.spec.tspasses all 301 tests.pnpm run preflightpasses on Node 24.19.0 / pnpm 12.8.2: 56 test files passed, 54,952 tests passed, 484 expected failures, 687 skipped; TypeScript checks pass. This local run used Linux arm64. The first attempt used a shallow clone without release tags, which caused only the docs-version test to fail; fetching the release tags and rerunning the same preflight passed.Scope
The regression cases cover a small offset range, a
multipleOfrange, a range nearNumber.MAX_SAFE_INTEGER, and a constrained float. This change does not add validation for out-of-contract custom distributors or numeric inputs beyond the tested cases. Hosted CI and maintainer review remain pending until a PR is opened.