Skip to content

Commit

Permalink
Big Number Format Fixes (#2956)
Browse files Browse the repository at this point in the history
* test: format bignumber to engineering bug

Add tests for correctly handling starting with more then 3 sig figs and targeting 1 or 2 sig figs

* lint:

* lint: reduce number literal sig figs

* fix: engineering notation for bignumber input

Corrects handling of cases where the input has 3 or more sig figs and the output is set to 1 or 2 sig figs.

* test: add negative format bignumber precision test

* fix: use BigNumber for all branches in toEngineering

Also, remove string type option from JSDoc for toEngineering since string does support the required interface for the function (the .e property, .mul member function, and the .constructor property would not be correct after this change)

* fix: precision 0 for fixed notation and bignumber

This fix differentiates precision === 0 and precision === undefined to.
After fix, format bignumber for precision 0 matches format number for precision 0.

Tests added as well

---------

Co-authored-by: Jos de Jong <wjosdejong@gmail.com>
  • Loading branch information
mgreminger and josdejong committed Jun 13, 2023
1 parent 3c59d1a commit 6fa5890
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/utils/bignumber/formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export function format (value, options) {
// determine precision from options
if (typeof options === 'number') {
precision = options
} else if (options.precision) {
} else if (options.precision !== undefined) {
precision = options.precision
}

Expand Down Expand Up @@ -212,7 +212,7 @@ export function format (value, options) {

/**
* Format a BigNumber in engineering notation. Like '1.23e+6', '2.3e+0', '3.500e-3'
* @param {BigNumber | string} value
* @param {BigNumber} value
* @param {number} [precision] Optional number of significant figures to return.
*/
export function toEngineering (value, precision) {
Expand All @@ -225,7 +225,8 @@ export function toEngineering (value, precision) {

let valueStr = valueWithoutExp.toPrecision(precision)
if (valueStr.indexOf('e') !== -1) {
valueStr = valueWithoutExp.toString()
const BigNumber = value.constructor
valueStr = new BigNumber(valueStr).toFixed()
}

return valueStr + 'e' + (e >= 0 ? '+' : '') + newExp.toString()
Expand Down
23 changes: 23 additions & 0 deletions test/unit-tests/function/string/format.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,19 @@ describe('format', function () {
assert.strictEqual(bigmath.format(oneThird, 18), '0.333333333333333333')
})

it('should format big numbers with fixed precision', function () {
const oneThird = math.bignumber(1).div(3)
const twoThirds = math.bignumber(2).div(3)
assert.strictEqual(math.format(oneThird, { notation: 'fixed', precision: 10 }), '0.3333333333')
assert.strictEqual(math.format(oneThird.mul(-1), { notation: 'fixed', precision: 10 }), '-0.3333333333')
assert.strictEqual(math.format(twoThirds, { notation: 'fixed', precision: 10 }), '0.6666666667')
assert.strictEqual(math.format(twoThirds, { notation: 'fixed', precision: 20 }), '0.66666666666666666667')
assert.strictEqual(math.format(oneThird, { notation: 'fixed', precision: 20 }), '0.33333333333333333333')
assert.strictEqual(math.format(oneThird, { notation: 'fixed', precision: 0 }), '0')
assert.strictEqual(math.format(twoThirds, { notation: 'fixed', precision: 0 }), '1')
assert.strictEqual(math.format(math.bignumber('123456789.123456789'), { notation: 'fixed', precision: 5 }), '123456789.12346')
})

describe('engineering notation', function () {
const bignumber = math.bignumber

Expand Down Expand Up @@ -335,6 +348,16 @@ describe('format', function () {
assert.strictEqual(math.format(bignumber('0.0000000000001234567890123456789'), { notation: 'engineering', precision: 3 }), '123e-15')
assert.strictEqual(math.format(bignumber('0.0000000000001234567890123456789'), { notation: 'engineering', precision: 16 }), '123.4567890123457e-15')
})
it('should format numbers starting with more than 3 sig figs that target 1 or 2 sig figs', function () {
assert.strictEqual(math.format(bignumber(0.333333333333333), { notation: 'engineering', precision: 1 }), '300e-3')
assert.strictEqual(math.format(bignumber(0.333333333333333), { notation: 'engineering', precision: 2 }), '330e-3')
assert.strictEqual(math.format(bignumber(33.33333333333), { notation: 'engineering', precision: 1 }), '30e+0')
assert.strictEqual(math.format(bignumber(333.33333333333), { notation: 'engineering', precision: 2 }), '330e+0')
assert.strictEqual(math.format(bignumber(333333.333333333), { notation: 'engineering', precision: 1 }), '300e+3')
assert.strictEqual(math.format(bignumber(777777.77777777), { notation: 'engineering', precision: 1 }), '800e+3')
assert.strictEqual(math.format(bignumber(777777.77777777), { notation: 'engineering', precision: 2 }), '780e+3')
assert.strictEqual(math.format(bignumber(-0.000000000777777), { notation: 'engineering', precision: 2 }), '-780e-12')
})
})

describe('non decimal base formatting', function () {
Expand Down

0 comments on commit 6fa5890

Please sign in to comment.