Skip to content

Commit

Permalink
Fix denominator precision loss and remove unnecessary safe integer ch…
Browse files Browse the repository at this point in the history
…eck for fractional part
  • Loading branch information
yaooqinn committed Jan 14, 2025
1 parent b1bb480 commit 6ab280a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 3 deletions.
4 changes: 2 additions & 2 deletions js/src/util/bn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ export function bigNumToNumber<T extends BN<BigNumArray>>(bn: T, scale?: number)
}
}
if (typeof scale === 'number') {
const denominator = BigInt(Math.pow(10, scale));
const denominator = BigInt(10) ** BigInt(scale);
const quotient = number / denominator;
const remainder = number % denominator;
return bigIntToNumber(quotient) + (bigIntToNumber(remainder) / bigIntToNumber(denominator));
return bigIntToNumber(quotient) + Number('0.' + `${remainder}`.padStart(scale, '0'));
}
return bigIntToNumber(number);
}
Expand Down
13 changes: 12 additions & 1 deletion js/test/unit/bn-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// under the License.

import * as Arrow from 'apache-arrow';
const { BN } = Arrow.util;
const { BN, bigNumToNumber } = Arrow.util;

describe(`BN`, () => {
test(`to detect signed numbers, unsigned numbers and decimals`, () => {
Expand Down Expand Up @@ -98,4 +98,15 @@ describe(`BN`, () => {
// const n6 = new BN(new Uint32Array([0x00000000, 0x00000000, 0x00000000, 0x80000000]), false);
// expect(n6.valueOf(1)).toBe(1.7014118346046923e+37);
});

test(`bigNumToNumber`, () => {
const n1 = BN.decimal(new Uint32Array([3, 2, 1, 0]));
expect(() => bigNumToNumber(n1)).toThrow('18446744082299486211');
/* eslint-disable @typescript-eslint/no-loss-of-precision */
expect(bigNumToNumber(n1, 10)).toBeCloseTo(1844674408.2299486);
expect(bigNumToNumber(n1, 15)).toBeCloseTo(18446.744082299486);
expect(bigNumToNumber(n1, 20)).toBeCloseTo(0.18446744082299486);
expect(bigNumToNumber(n1, 25)).toBeCloseTo(0.0000018446744082299486);
/* eslint-enable @typescript-eslint/no-loss-of-precision */
});
});

0 comments on commit 6ab280a

Please sign in to comment.