Skip to content

Commit

Permalink
feat: ratio.quantize() shouldn't increase precision unnecessarily
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris-Hibbert committed Aug 19, 2024
1 parent c4520c5 commit cbb5b55
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 10 deletions.
4 changes: 4 additions & 0 deletions packages/zoe/src/contractSupport/ratio.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ export const ratiosSame = (left, right) => {
export const quantize = (ratio, newDen) => {
const oldDen = ratio.denominator.value;
const oldNum = ratio.numerator.value;
if (oldDen < newDen) {
return ratio;
}

const newNum =
newDen === oldDen ? oldNum : bankersDivide(oldNum * newDen, oldDen);
return makeRatio(
Expand Down
41 changes: 31 additions & 10 deletions packages/zoe/test/unitTests/contractSupport/ratio.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -501,25 +501,25 @@ const { brand } = makeIssuerKit('moe');

test('ratio - quantize', t => {
/** @type {Array<[numBefore: bigint, denBefore: bigint, numAfter: bigint, denAfter: bigint]>} */
const cases = /** @type {const} */ [
const cases = [
[1n, 1n, 1n, 1n],
[10n, 10n, 10n, 10n],
[2n * 10n ** 9n, 1n * 10n ** 9n, 20n, 10n],

[12345n, 12345n, 100n, 100n],
[12345n, 12345n, 100000n, 100000n],
[12345n, 12345n, 10n ** 15n, 10n ** 15n],

[12345n, 123n, 100365854n, 10n ** 6n],
[12345n, 123n, 10036585n, 10n ** 5n],
[12345n, 123n, 1003659n, 10n ** 4n],
[12345n, 123n, 100366n, 10n ** 3n],
[12345n, 123n, 10037n, 10n ** 2n],
[12345n, 123n, 1004n, 10n ** 1n],
[12345n, 123n, 100n, 10n ** 0n],

[12345n, 12345n, 100n, 100n],
];

for (const [numBefore, denBefore, numAfter, denAfter] of cases) {
for (const [
numBefore,
denBefore,
numAfter,
target,
denAfter = target,
] of cases) {
const before = makeRatio(numBefore, brand, denBefore, brand);
const after = makeRatio(numAfter, brand, denAfter, brand);
t.deepEqual(
Expand All @@ -530,6 +530,27 @@ test('ratio - quantize', t => {
}
});

test('ratio - quantize - leave it alone', t => {
const cases = [
[12345n, 123n, 10n ** 5n, 12345n, 123n],
[12345n, 123n, 10n ** 4n, 12345n, 123n],
[12345n, 123n, 10n ** 3n, 12345n, 123n],

[12345n, 12345n, 100_000n, 12345n, 12345n],
[12345n, 12345n, 10n ** 15n, 12345n, 12345n],
];

for (const [numPre, denPre, qTarget, numAfter, denAfter] of cases) {
const before = makeRatio(numPre, brand, denPre, brand);
const after = makeRatio(numAfter, brand, denAfter, brand);
t.deepEqual(
quantize(before, qTarget),
after,
`${numPre}/${denPre} quantized to ${qTarget} should be ${numAfter}/${denAfter}`,
);
}
});

test('ratio - parse', t => {
const { brand: moeBrand } = makeIssuerKit('moe');
const { brand: larryBrand } = makeIssuerKit('larry');
Expand Down

0 comments on commit cbb5b55

Please sign in to comment.