Skip to content

Commit

Permalink
fix: decimal javascript calculation (close faker-js#331)
Browse files Browse the repository at this point in the history
  • Loading branch information
xDivisionByZerox authored and franznoel committed Feb 24, 2022
1 parent 23a262a commit 506d5c7
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"c8": "~7.11.0",
"conventional-changelog-cli": "~2.2.2",
"cypress": "~9.5.0",
"decimal.js": "^10.3.1",
"esbuild": "~0.14.23",
"eslint": "~8.9.0",
"eslint-config-prettier": "~8.4.0",
Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/datatype.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Faker } from '.';
import Decimal from 'decimal.js';

/**
* Module to generate various primitive values and data types.
Expand Down Expand Up @@ -72,7 +73,10 @@ export class Datatype {
)
);
// Workaround problem in Float point arithmetics for e.g. 6681493 / 0.01
randomNumber = randomNumber / (1 / options.precision);
const decimalPrecision = new Decimal(1)
.dividedBy(options?.precision)
.toNumber();
randomNumber = randomNumber / decimalPrecision;

return randomNumber;
}
Expand Down
48 changes: 48 additions & 0 deletions test/datatype.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const seededRuns = [
withMinAndMax: -1,
withMax: 26,
withMinAndMaxAndPrecision: -0.43,
withMinAndMaxAndPrecision5: -0.42605,
withMinAndMaxAndPrecision9: -0.426047312,
},
float: {
noArgs: 37453.64,
Expand All @@ -20,6 +22,8 @@ const seededRuns = [
withMinAndMax: -0.43,
withMax: 25.84,
withMinAndMaxAndPrecision: -0.4261,
withMinAndMaxAndPrecision5: -0.42605,
withMinAndMaxAndPrecision9: -0.426047312,
},
datetime: {
// TODO @Shinigami92 2022-01-29: We will fix the deterministic in #343
Expand Down Expand Up @@ -81,6 +85,8 @@ const seededRuns = [
withMinAndMax: -13,
withMax: 18,
withMinAndMaxAndPrecision: -12.92,
withMinAndMaxAndPrecision5: -12.91526,
withMinAndMaxAndPrecision9: -12.915260943,
},
float: {
noArgs: 26202.2,
Expand All @@ -89,6 +95,8 @@ const seededRuns = [
withMinAndMax: -12.92,
withMax: 18.08,
withMinAndMaxAndPrecision: -12.9153,
withMinAndMaxAndPrecision5: -12.91526,
withMinAndMaxAndPrecision9: -12.915260943,
},
datetime: {
// TODO @Shinigami92 2022-01-29: We will fix the deterministic in #343
Expand Down Expand Up @@ -150,6 +158,8 @@ const seededRuns = [
withMinAndMax: 61,
withMax: 64,
withMinAndMaxAndPrecision: 61.07,
withMinAndMaxAndPrecision5: 61.06574,
withMinAndMaxAndPrecision9: 61.065737066,
},
float: {
noArgs: 92851.09,
Expand All @@ -158,6 +168,8 @@ const seededRuns = [
withMinAndMax: 61.07,
withMax: 64.07,
withMinAndMaxAndPrecision: 61.0658,
withMinAndMaxAndPrecision5: 61.06574,
withMinAndMaxAndPrecision9: 61.065737066,
},
datetime: {
// TODO @Shinigami92 2022-01-29: We will fix the deterministic in #343
Expand Down Expand Up @@ -290,6 +302,32 @@ describe('datatype', () => {
});
expect(actual).toEqual(expectations.number.withMinAndMaxAndPrecision);
});

it('should return a deterministic value for given min, max and precision of 0.00001', () => {
faker.seed(seed);

const actual = faker.datatype.number({
min: -42,
max: 69,
precision: 0.00001,
});
expect(actual).toEqual(
expectations.number.withMinAndMaxAndPrecision5
);
});

it('should return a deterministic value for given min, max and precision of 0.000000001', () => {
faker.seed(seed);

const actual = faker.datatype.number({
min: -42,
max: 69,
precision: 0.000000001,
});
expect(actual).toEqual(
expectations.number.withMinAndMaxAndPrecision9
);
});
});

describe('float', () => {
Expand Down Expand Up @@ -469,6 +507,16 @@ describe('datatype', () => {
expect(number).toBe(Number(number.toFixed(3)));
});

it('should return a random float given a precision value of 0.00001', () => {
const number = faker.datatype.float(0.00001);
expect(number).toBe(Number(number.toFixed(5)));
});

it('should return a random float given a precision value of 0.000000001', () => {
const number = faker.datatype.float(0.000000001);
expect(number).toBe(Number(number.toFixed(9)));
});

it('should return a random number given a maximum value as Object', () => {
const options = { max: 10 };
expect(faker.datatype.float(options)).greaterThanOrEqual(0);
Expand Down

0 comments on commit 506d5c7

Please sign in to comment.