Add "toFloatRatio" helper method (#1750)

Add a numerically-naive method for calculating the floating point ratio
between grain values, as it is needed in #1743.

Following discussion in [this review], we hope that @wchargin will
re-write this method later to have better precision.

Test plan: Attached unit tests should pass.

[this review]: https://github.com/sourcecred/sourcecred/pull/1715#discussion_r396909459

Paired with @hammadj
This commit is contained in:
Dandelion Mané 2020-04-20 17:12:54 -07:00 committed by GitHub
parent 898282becc
commit 791c05e1fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 0 deletions

View File

@ -139,3 +139,15 @@ export function multiplyFloat(grain: Grain, num: number): Grain {
export function fromApproximateFloat(f: number): Grain {
return multiplyFloat(ONE, f);
}
/**
* Approximates the division of two grain values
*
* This naive implementation of grain division converts the given values
* to floats and performs simple floating point division.
*
* Do not assume this will be precise!
*/
export function toFloatRatio(numerator: Grain, denominator: Grain): number {
return Number(numerator) / Number(denominator);
}

View File

@ -7,6 +7,7 @@ import {
ZERO,
fromApproximateFloat,
multiplyFloat,
toFloatRatio,
} from "./grain";
describe("src/grain/grain", () => {
@ -117,4 +118,32 @@ describe("src/grain/grain", () => {
expect(fromApproximateFloat(0.1)).toEqual(ONE / 10n);
});
});
describe("toFloatRatio", () => {
it("handles a one-to-one ratio", () => {
expect(toFloatRatio(ONE, ONE)).toEqual(1);
});
it("handles a larger numerator", () => {
// $ExpectFlowError
expect(toFloatRatio(ONE * 2n, ONE)).toEqual(2);
});
it("handles fractional numbers", () => {
// $ExpectFlowError
expect(toFloatRatio(ONE * 5n, ONE * 2n)).toEqual(2.5);
});
it("calculates repeating decimal ratios", () => {
// $ExpectFlowError
expect(toFloatRatio(ONE * 5n, ONE * 3n)).toEqual(5 / 3);
});
it("approximates correctly when Grain values are not exactly equal", () => {
// $ExpectFlowError
const almostOne = ONE - 1n;
expect(toFloatRatio(ONE, almostOne)).toEqual(1);
});
it("handles irrational numbers", () => {
const bigPi = multiplyFloat(ONE, Math.PI);
// $ExpectFlowError
expect(toFloatRatio(bigPi, ONE * 2n)).toEqual(Math.PI / 2);
});
});
});