I'm trying to round a float number in Javascript in the same way that I do it in PHP; but I can not make both languages round in the same way the following number:6.404999999999999
When I use PHP round I get: 6.41
, but when I trying to round with Javascript I always get 6.40
INFO: The correct answer is
My Javascript attempts:
Attempt #1:
module.exports = function round (value, precision, mode) {
var m, f, isHalf, sgn // helper variables
// making sure precision is integer
precision |= 0
m = Math.pow(10, precision)
value *= m
// sign of the number
sgn = (value > 0) | -(value < 0)
isHalf = value % 1 === 0.5 * sgn
f = Math.floor(value)
if (isHalf) {
switch (mode) {
case 'PHP_ROUND_HALF_DOWN':
// rounds .5 toward zero
value = f + (sgn < 0)
break
case 'PHP_ROUND_HALF_EVEN':
// rouds .5 towards the next even integer
value = f + (f % 2 * sgn)
break
case 'PHP_ROUND_HALF_ODD':
// rounds .5 towards the next odd integer
value = f + !(f % 2)
break
default:
// rounds .5 away from zero
value = f + (sgn > 0)
}
}
return (isHalf ? value : Math.round(value)) / m
}
Extracted from: /
Attempt #2:
round(decimal: number, decimalPoints: number): number{
let roundedValue = Math.round(decimal * Math.pow(10, decimalPoints)) / Math.pow(10, decimalPoints);
console.log(`Rounded ${decimal} to ${roundedValue}`);
return roundedValue;
}
Extracted from:
I tried with other solutions... but without success.
Could someone tell me how to get the rounding of Javascript to act like PHP's?
Could you tell me why they work in different ways in the case I explain?
I'm trying to round a float number in Javascript in the same way that I do it in PHP; but I can not make both languages round in the same way the following number:6.404999999999999
When I use PHP round I get: 6.41
, but when I trying to round with Javascript I always get 6.40
INFO: The correct answer is https://stackoverflow.com/a/54721202/4359029
My Javascript attempts:
Attempt #1:
module.exports = function round (value, precision, mode) {
var m, f, isHalf, sgn // helper variables
// making sure precision is integer
precision |= 0
m = Math.pow(10, precision)
value *= m
// sign of the number
sgn = (value > 0) | -(value < 0)
isHalf = value % 1 === 0.5 * sgn
f = Math.floor(value)
if (isHalf) {
switch (mode) {
case 'PHP_ROUND_HALF_DOWN':
// rounds .5 toward zero
value = f + (sgn < 0)
break
case 'PHP_ROUND_HALF_EVEN':
// rouds .5 towards the next even integer
value = f + (f % 2 * sgn)
break
case 'PHP_ROUND_HALF_ODD':
// rounds .5 towards the next odd integer
value = f + !(f % 2)
break
default:
// rounds .5 away from zero
value = f + (sgn > 0)
}
}
return (isHalf ? value : Math.round(value)) / m
}
Extracted from: http://locutus.io/php/math/round/
Attempt #2:
round(decimal: number, decimalPoints: number): number{
let roundedValue = Math.round(decimal * Math.pow(10, decimalPoints)) / Math.pow(10, decimalPoints);
console.log(`Rounded ${decimal} to ${roundedValue}`);
return roundedValue;
}
Extracted from: https://stackoverflow.com/a/50918962/4359029
I tried with other solutions... but without success.
Could someone tell me how to get the rounding of Javascript to act like PHP's?
Could you tell me why they work in different ways in the case I explain?
Share Improve this question edited Oct 2, 2020 at 19:51 tomloprod asked Nov 23, 2018 at 16:36 tomloprodtomloprod 7,8826 gold badges52 silver badges70 bronze badges 1 |4 Answers
Reset to default 5I think the best answer is the next:
function roundLikePHP(num, dec){
var num_sign = num >= 0 ? 1 : -1;
return parseFloat((Math.round((num * Math.pow(10, dec)) + (num_sign * 0.0001)) / Math.pow(10, dec)).toFixed(dec));
}
I tried the other solutions with 1.015
and doesn't work as expected.
This solution works well, like PHP round, with all the numbers I tried.
You could do it like this:
function roundToXDigits(value, digits)
{
if (!digits) {
digits = 2;
}
value = value * Math.pow(10, digits);
value = Math.round(value);
value = value / Math.pow(10, digits);
return value
}
var num = roundToXDigits(6.404999999999999, 3); //creates 6.405
console.log(roundToXDigits(num, 2)); //creates 6.41
The problem is, JavaScript technically isn't wrong. 6.4049 -> becomes 6.405 when you round (which, to 2dp is 6.40) which is why it's not working as expected. You have to run the function twice to round 405 -> 41.
Source: JavaScript math, round to two decimal places
^^ extension usage of Bryce's answer.
You can use toPrecision Function
It will rounded by the precision
provided. Here I rounded by 4
to get 6.405
and then rounded by 3
to get 6.41
parseFloat((6.404999999999999).toPrecision(4)).toPrecision(3);
console.log(parseFloat((6.404999999999999).toPrecision(4)).toPrecision(3));
You might try
console.log(Number(n.toFixed(3)).toFixed(2));
eg.
var n = 6.404999999999999;
console.log(n.toFixed(2)); //=> 6.40
console.log(n.toFixed(3)); //=> 6.405
6.405
but is unable to display it accurately in decimal. this is a good read about this the problem is that in all likelyhood when you send the decimal representation of that number to JavaScript the accurate binary representation is lost and JavaScript has to work with noisy data. I doubt there is anything to do other than send the ops to JavaScript and have it do the calculation from scratch – apokryfos Commented Nov 23, 2018 at 16:59