-
-
Notifications
You must be signed in to change notification settings - Fork 932
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generating a float with precision of 0.00001 gives larger precision number #2567
Comments
Hi @clocke3 , thank you for your bug. From your description (and screenshot!) this seems to be legit. |
The example doesn't work for me either.
I assume the bug is related to a float precision issue. |
@xDivisionByZerox I apologize I am new to this issue making and checked the section on "creating a PR for issue" on mistake. |
@ST-DDT Yes it is. Looks like it existed in 8.0.2, 8.2.0, and I did test it out using 8.3.1 locally. I will try to see if I can produce reproduction code using 8.3.1. |
No problem at all. If you have a suggestion for an algorithm that might fix this issue feel free to post it here anyway. |
I don't think we changed anything significant in the method in this major version, so the problem is likely still there. |
Definitely a JS floating point issue. Not all floats can be exactly represented in Javascript. if (precision !== undefined) {
if (precision <= 0) {
throw new FakerError(`Precision should be greater than 0.`);
}
const factor = 1 / precision;
const int = this.int({
min: min * factor,
max: max * factor,
});
return int / factor;
} The code
|
You could do some kind of special case for precisions which are powers of 10 (most common case), like: const logPrecision = Math.log10(precision)
if (Number.isInteger(logPrecision)) {
return parseFloat((int / factor).toFixed(-logPrecision));
} else {
return int / factor;
} |
Similarly you would still have issues with precisions which are not powers of 10 e.g.: > [ ...new Set( Array.from({ length: 500 }, () => faker.number.float({ min: 0, max: 1, precision: 0.3, }) ) ), ].sort();
[ 0, 0.3, 0.6, 0.8999999999999999 ] |
This might also work for non power 10 cases. const logPrecision = precision.toString().replace(/\d+\./, '').length;
return parseFloat((int / factor).toFixed(logPrecision)); Not sure about the performance implications though. |
Another option might be if 1/precision is "almost" an integer (within a small epsilon value) then we round it to an integer |
Any movement on this in development or still brainstorming? |
Still under discussion. As a workaround,
|
I think i have a fairly neat solution in #2581 - please take a look |
Pre-Checks
Describe the bug
When trying to generate a float using faker.number.float({ precision: 0.00001 }), the generated float generates a number with more than 5 decimal place values after the decimal point. Generated float values where precision is set to 0.1 to 0.0001, and 0.000001 and greater are consistently working.
Minimal reproduction code
https://runkit.com/embed/g86r0jyau1rk
Additional Context
Using faker-js to write playwright tests; example shows a generated value logged out where it was set to faker.number.float({ max: 99999.99999, precision: 0.00001 }).
Environment Info
System: OS: Linux 5.10 Ubuntu 20.04.6 LTS (Focal Fossa) CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-1280P Memory: 6.67 GB / 15.46 GB Container: Yes Shell: 5.0.17 - /bin/bash Binaries: Node: 20.9.0 - /usr/local/bin/node Yarn: 3.6.3 - /usr/local/bin/yarn npm: 10.2.3 - /usr/local/bin/npm npmPackages: @faker-js/faker: ^8.0.2 => 8.0.2
Which module system do you use?
Used Package Manager
npm
The text was updated successfully, but these errors were encountered: