Skip to content

Commit

Permalink
fixes a bug: truncate(1.670006528897705e-10, 2) → 1.67, failed to rec…
Browse files Browse the repository at this point in the history
…ognize the scientific notation...
  • Loading branch information
xpl committed Nov 1, 2017
1 parent a42b7e6 commit 63fab0a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
23 changes: 23 additions & 0 deletions js/base/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,36 @@ const safeValue = (object, key, defaultValue = undefined) => {
return ((key in object) && object[key]) ? object[key] : defaultValue
}


// See https://stackoverflow.com/questions/1685680/how-to-avoid-scientific-notation-for-large-numbers-in-javascript for discussion

function toFixed (x) { // avoid scientific notation for too large and too small numbers

if (Math.abs (x) < 1.0) {
const e = parseInt (x.toString ().split ('e-')[1])
if (e) {
x *= Math.pow (10, e-1)
x = '0.' + (new Array (e)).join ('0') + x.toString ().substring (2)
}
} else {
const e = parseInt (x.toString ().split ('+')[1])
if (e > 20) {
e -= 20
x /= Math.pow (10, e)
x += (new Array (e+1)).join ('0')
}
}
return x
}

// See https://stackoverflow.com/questions/4912788/truncate-not-round-off-decimal-numbers-in-javascript for discussion

// > So, after all it turned out, rounding bugs will always haunt you, no matter how hard you try to compensate them.
// > Hence the problem should be attacked by representing numbers exactly in decimal notation.

const truncate_regExpCache = []
, truncate = (num, precision = 0) => {
num = toFixed (num)
const re = truncate_regExpCache[precision] || (truncate_regExpCache[precision] = new RegExp("([-]*\\d+\\.\\d{" + precision + "})(\\d)"))
const [,result] = num.toString ().match (re) || [null, num]
return parseFloat (result)
Expand Down
1 change: 1 addition & 0 deletions js/test/test_base.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ describe ('ccxt base code', () => {
assert.equal (ccxt.truncate ( 17.569, 2), 17.56)
assert.equal (ccxt.truncate (49.9999, 4), 49.9999)
assert.equal (ccxt.truncate (49.99999, 4), 49.9999)
assert.equal (ccxt.truncate (1.670006528897705e-10, 4), 0)
})

it ('parseBalance() works', () => {
Expand Down

0 comments on commit 63fab0a

Please sign in to comment.