javascript - Why is 10000000000000.126.toString() 1000000000000.127 (and what can I do to prevent it)? -
why 10000000000000.126.tostring() 1000000000000.127 , 100000000000.126.tostring() not?
i think must have maximum value of number in js (as per this question), related floating point operations , how?
i'm asking because wrote function format number using thousands separators , prevent this.
function th(n,sep) { sep = sep || '.'; var dec = n.tostring().split(/[,.]/), narr = dec[0].split(''), isdot = /\./.test(sep); return function tt(n) { return n.length > 3 ? tt(n.slice(0,n.length-3)).concat(n.slice(n.length-3).join('')) : [n.join('')] ; }(narr) .join(sep) + (dec[1] ? (isdot?',':'.') + dec[1] : ''); } sep1000(10000000000000.126); //=> 10.000.000.000.000,127 sep1000(1000000000000.126); //=> 1.000.000.000.000,126
because not numbers can represented floating point (javascript uses double-precision 64-bit format ieee 754 numbers), rounding errors come in. instance:
alert(0.1 + 0.2); // "0.30000000000000004" all numbering systems limited storage (e.g., numbering systems) have issue, , used dealing our decimal system (which can't accurately represent "one third") , surprised of different values floating-point formats used computers can't accurately represent. sort of thing why you're seeing more , more "decimal" style types out there (java has bigdecimal, c# has decimal, etc.), use our style of number representation (at cost) , useful applications rounding needs align our expectations more closely (such financial apps).
update: haven't tried, may able work around manipulating values bit before grab strings. instance, works specific example (live copy):
code:
function display(msg) { var p = document.createelement('p'); p.innerhtml = msg; document.body.appendchild(p); } function precisetostring(num) { var floored = math.floor(num), fraction = num - floored, rv, fractionstring, n; rv = string(floored); n = rv.indexof("."); if (n >= 0) { rv = rv.substring(0, n); } fractionstring = string(fraction); if (fractionstring.substring(0, 2) !== "0.") { return string(num); // punt } rv += "." + fractionstring.substring(2); return rv; } display(precisetostring(10000000000000.126)); result:
10000000000000.126953125
...which can, of course, truncated see fit. of course, it's important note 10000000000000.126953125 != 10000000000000.126. think ship had sailed (e.g., number contained imprecise value), given seeing .127. can't see way know original went 3 places, not number.
i'm not saying above in way reliable, you'd have put through paces prove it's (which say, i'm) not doing stoopid there. , again, since don't know precision ended in first place, i'm not sure how helpful is.
Comments
Post a Comment