Is there a way to proper round the number 35.855 to have two decimals in javascript? Trying to round it has different solutions based on the environment (35.85 in Chrome, 35.86 in IE9).
I was looking for a solution at which javascript does wrong rounding for the decimals (rounding .5 values down instead up) and haven't found a solution that covered all the values that I had. They behaved other in different environments / browsers.
console.log(Math.round(35.855*100)/100);
// result: 35.85 (IE9 : 35.86, Chrome: 35.85 ???)
console.log((35.855).toFixed(2));
// result: 35.85
Make rounding of 1 character after the decimal part:
const round = (num, digits = 2) => {
const str = num.toString(), idx = str.indexOf('.');
if (idx < 0) return num;
const left = str[idx + 1 + digits]; // round this char
if (!left) return num;
return parseFloat(str.slice(0, idx + 1 + digits)) +
(left >= 5) * (str[0] === '-' ? -1 : 1) / 10 ** digits;
}
[35.855, 35.8549999, [-35.8549999, 3], 35.895, 35.8, 35].forEach(num =>
console.log(JSON.stringify(num), '->', round(...[].concat(num))));
And a benchmark:
Cycles: 1000000 / Chrome/117
------------------------------------------------------------
Alexander slice 151/min 1.0x 163 166 159 151 169
Sercan Samet Savran 845/min 5.6x 846 845 846 851 859
------------------------------------------------------------
https://github.com/silentmantra/benchmark
<script benchmark data-count="1000000">
// @benchmark Alexander slice
const round = (num, digits = 2) => {
const str = num.toString();
const idx = str.indexOf('.');
if(idx < 0){
return num;
}
const left = str[idx + 1 + digits];
return left ? parseFloat(str.slice(0, idx + 1 + digits)) +(left >= 5) * (str[0] === '-' ? -1 : 1)/ 10 ** digits : num;
}
// @run
round(35.855);
round(35.8549999);
round(35.8549999, 3);
round(35.85);
round(35.8);
round(35);
// @benchmark Sercan Samet Savran
function roundToTwoDecimal(myNumber){
let myStrNumber = myNumber.toString();
// checking our number has decimals and if enough decimal points are present
if(myStrNumber.split(".").length > 1 && myStrNumber.split(".")[1].length > 2){
// doubling the last decimal e.g. 35.855 is now = 35.8555 and parsing back to float
myStrNumber += myStrNumber.substring(myStrNumber.length-1);
myNumber = parseFloat(myStrNumber);
} // no additional decimal needed here.
// returning the myNumber*100 = 3585.55 ---round--> 3586 / 100 = 35.86
return Math.round(myNumber*100)/100;
}
// @run
roundToTwoDecimal(35.855);
roundToTwoDecimal(35.8549999);
roundToTwoDecimal(35.8549999, 3);
roundToTwoDecimal(35.85);
roundToTwoDecimal(35.8);
roundToTwoDecimal(35);
</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>