I need to round for example 6.688689
to 6.7
, but it always shows me 7
.
My method:
Math.round(6.688689);
//or
Math.round(6.688689, 1);
//or
Math.round(6.688689, 2);
But result always is the same 7
... What am I doing wrong?
I need to round for example 6.688689
to 6.7
, but it always shows me 7
.
My method:
Math.round(6.688689);
//or
Math.round(6.688689, 1);
//or
Math.round(6.688689, 2);
But result always is the same 7
... What am I doing wrong?
Number((6.688689).toFixed(1)); // 6.7
var number = 6.688689;
var roundedNumber = Math.round(number * 10) / 10;
Use toFixed()
function.
(6.688689).toFixed(); // equal to "7"
(6.688689).toFixed(1); // equal to "6.7"
(6.688689).toFixed(2); // equal to "6.69"
Upd (2019-10). Thanks to Reece Daniels code below now available as a set of functions packed in npm-package expected-round (take a look).
You can use helper function from MDN example. Than you'll have more flexibility:
Math.round10(5.25, 0); // 5
Math.round10(5.25, -1); // 5.3
Math.round10(5.25, -2); // 5.25
Math.round10(5, 0); // 5
Math.round10(5, -1); // 5
Math.round10(5, -2); // 5
Upd (2019-01-15). Seems like MDN docs no longer have this helper funcs. Here's a backup with examples:
// Closure
(function() {
/**
* Decimal adjustment of a number.
*
* @param {String} type The type of adjustment.
* @param {Number} value The number.
* @param {Integer} exp The exponent (the 10 logarithm of the adjustment base).
* @returns {Number} The adjusted value.
*/
function decimalAdjust(type, value, exp) {
// If the exp is undefined or zero...
if (typeof exp === 'undefined' || +exp === 0) {
return Math[type](value);
}
value = +value;
exp = +exp;
// If the value is not a number or the exp is not an integer...
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
return NaN;
}
// If the value is negative...
if (value < 0) {
return -decimalAdjust(type, -value, exp);
}
// Shift
value = value.toString().split('e');
value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}
// Decimal round
if (!Math.round10) {
Math.round10 = function(value, exp) {
return decimalAdjust('round', value, exp);
};
}
// Decimal floor
if (!Math.floor10) {
Math.floor10 = function(value, exp) {
return decimalAdjust('floor', value, exp);
};
}
// Decimal ceil
if (!Math.ceil10) {
Math.ceil10 = function(value, exp) {
return decimalAdjust('ceil', value, exp);
};
}
})();
Usage examples:
// Round
Math.round10(55.55, -1); // 55.6
Math.round10(55.549, -1); // 55.5
Math.round10(55, 1); // 60
Math.round10(54.9, 1); // 50
Math.round10(-55.55, -1); // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1); // -50
Math.round10(-55.1, 1); // -60
Math.round10(1.005, -2); // 1.01 -- compare this with Math.round(1.005*100)/100 above
Math.round10(-1.005, -2); // -1.01
// Floor
Math.floor10(55.59, -1); // 55.5
Math.floor10(59, 1); // 50
Math.floor10(-55.51, -1); // -55.6
Math.floor10(-51, 1); // -60
// Ceil
Math.ceil10(55.51, -1); // 55.6
Math.ceil10(51, 1); // 60
Math.ceil10(-55.59, -1); // -55.5
Math.ceil10(-59, 1); // -50
> +(6.688687).toPrecision(2)
6.7
A Number
object in JavaScript has a method that does exactly what you need. That method is Number.toPrecision([precision])
.
Just like with .toFixed(1)
it converts the result into a string, and it needs to be converted back into a number. Done using the +
prefix here.
simple benchmark on my laptop:
number = 25.645234 typeof number
50000000 x number.toFixed(1) = 25.6 typeof string / 17527ms
50000000 x +(number.toFixed(1)) = 25.6 typeof number / 23764ms
50000000 x number.toPrecision(3) = 25.6 typeof string / 10100ms
50000000 x +(number.toPrecision(3)) = 25.6 typeof number / 18492ms
50000000 x Math.round(number*10)/10 = 25.6 typeof number / 58ms
string = 25.645234 typeof string
50000000 x Math.round(string*10)/10 = 25.6 typeof number / 7109ms
you can repeat this benchmark on your own setup with node or your browser's console:
function bench(name, func) {
console.log(name, typeof func(), func())
console.time(name)
Array(50000000).forEach(func)
console.timeEnd(name)
}
number = 25.645234
string = '25.645234'
bench( 'toFixed', () => number.toFixed(1) )
bench( '+toFixed', () => +(number.toFixed(1)) )
bench( 'toPrecision', () => number.toPrecision(3) )
bench( '+toPrecision', () => +(number.toPrecision(3)) )
bench( 'Math.round(num)', () => Math.round(number*10)/10 )
bench( 'Math.round(str)', () => Math.round(string*10)/10 )
If you not only want to use toFixed()
but also ceil()
and floor()
on a float then you can use the following function:
function roundUsing(func, number, prec) {
var tempnumber = number * Math.pow(10, prec);
tempnumber = func(tempnumber);
return tempnumber / Math.pow(10, prec);
}
Produces:
> roundUsing(Math.floor, 0.99999999, 3)
0.999
> roundUsing(Math.ceil, 0.1111111, 3)
0.112
UPD:
The other possible way is this:
Number.prototype.roundUsing = function(func, prec){
var temp = this * Math.pow(10, prec)
temp = func(temp);
return temp / Math.pow(10, prec)
}
Produces:
> 6.688689.roundUsing(Math.ceil, 1)
6.7
> 6.688689.roundUsing(Math.round, 1)
6.7
> 6.688689.roundUsing(Math.floor, 1)
6.6
My extended round function:
function round(value, precision) {
if (Number.isInteger(precision)) {
var shift = Math.pow(10, precision);
// Limited preventing decimal issue
return (Math.round( value * shift + 0.00000000000001 ) / shift);
} else {
return Math.round(value);
}
}
Example Output:
round(123.688689) // 123
round(123.688689, 0) // 123
round(123.688689, 1) // 123.7
round(123.688689, 2) // 123.69
round(123.688689, -2) // 100
round(1.015, 2) // 1.02
There is the alternative .toLocaleString() to format numbers, with a lot of options regarding locales, grouping, currency formatting, notations. Some examples:
Round to 1 decimal, return a float:
const n = +6.688689.toLocaleString('fullwide', {maximumFractionDigits:1})
console.log(
n, typeof n
)
Round to 2 decimals, format as currency with specified symbol, use comma grouping for thousands:
console.log(
68766.688689.toLocaleString('fullwide', {maximumFractionDigits:2, style:'currency', currency:'USD', useGrouping:true})
)
Format as locale currency:
console.log(
68766.688689.toLocaleString('fr-FR', {maximumFractionDigits:2, style:'currency', currency:'EUR'})
)
Round to minimum 3 decimal, force zeroes to display:
console.log(
6.000000.toLocaleString('fullwide', {minimumFractionDigits:3})
)
Percent style for ratios. Input * 100 with % sign
console.log(
6.688689.toLocaleString('fullwide', {maximumFractionDigits:2, style:'percent'})
)
See below
var original = 28.59;
var result=Math.round(original*10)/10
will return you returns 28.6
Hope this is what you want..
I have very good solution with if toFixed() is not working.
function roundOff(value, decimals) {
return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}
Example
roundOff(10.456,2) //output 10.46
Math.round((6.688689 + Number.EPSILON) * 10) / 10
Solution stolen from https://stackoverflow.com/a/11832950/2443681
This should work with nearly any float value. It doesn't force decimal count though. It's not clear whether this was a requirement. Should be faster than using toFixed()
, which has other issues as well based on the comments to other answers.
A nice utility function to round in needed decimal precision:
const roundToPrecision = (value, decimals) => {
const pow = Math.pow(10, decimals);
return Math.round((value + Number.EPSILON) * pow) / pow;
};
float(value,ndec);
function float(num,x){
this.num=num;
this.x=x;
var p=Math.pow(10,this.x);
return (Math.round((this.num).toFixed(this.x)*p))/p;
}
+((6.688689 * (1 + Number.EPSILON)).toFixed(1)); // 6.7
+((456.1235 * (1 + Number.EPSILON)).toFixed(3)); // 456.124
I think this function can help.
function round(value, ndec){
var n = 10;
for(var i = 1; i < ndec; i++){
n *=10;
}
if(!ndec || ndec <= 0)
return Math.round(value);
else
return Math.round(value * n) / n;
}
round(2.245, 2) //2.25
round(2.245, 0) //2
Minor tweak to this answer:
function roundToStep(value, stepParam) {
var step = stepParam || 1.0;
var inv = 1.0 / step;
return Math.round(value * inv) / inv;
}
roundToStep(2.55, 0.1) = 2.6
roundToStep(2.55, 0.01) = 2.55
roundToStep(2, 0.01) = 2
How to correctly round decimals in a number (basics):
We start from far right number:
>=
to 5 rounding is required, we will then report a 1 to the first number on the left. <
to 5 means no roundingOnce you know if you need to report a value or not you can delete the last number and repeat the operation.
Beware there is a special case when you need to report a value and the number that must be added to that value is 9
: in such case you will have to change the number value for 0
before reporting a 1 on the following left number.
For some of the failing answers it looks like decimals are splitted left to right for the required amount of decimals without even caring about the rounding.
Now that this is stated here is a function that will round a provided float
value recursively using the above logic.
function roundFloatR(n, precision = 0, opts = { return: 'number' }) { // Use recursivity
if ( precision == 0 ) { // n will be rounded to the closest integer
if (opts.return == 'number') return Math.round(n);
else if (opts.return == 'string') return `${Math.round(n)}`;
} else {
let ns = `${n}`.split(''); // turns float into a string before splitting it into a char array
if ( precision < 0 ) { // precision is a negative number
precision += ns.length - 1; // precision equals last index of ns - its actual value
} else if ( precision > 0 ) { // precision is a positive number
if ( ns.indexOf('.') > -1 )
precision += ns.indexOf('.'); // precision equals its value + the index of the float separator in the string / array of char
}
// RECURSIVE FUNCTION: loop from the end of ns to the precision index while rounding the values
// index: index in the ns char array, rep: reported value, (INTERNAL_VAR, cn: current number)
const recursive = (index, rep) => {
let cn = parseInt(ns[index]); // get the current number from ns at index
if (index <= precision) { // current index inferior or equal to the defined precision index (end of rounding)
if (rep) { // if a reported value exists
cn += rep; // add reported value to current number
if (cn == 10) { // extends rounding for special case of decimals ending with 9 + reported value
ns[index] = '0';
recursive( (index - 1), 1 ); // calls recursive() again with a reported value
} else if (cn < 10)
ns[index] = `${cn}`;
}
} else if (index > precision) { // current index superior to defined precision index
ns.pop(); // each passage in this block will remove the last entry of ns
if (rep) cn += rep; // adds reported value (if it exists) to current number
if ( cn >= 5 ) // ROUNDING
recursive( (index - 1), 1 ); // calls recursive() again with a reported value
else // NO ROUNDING
recursive( index - 1 ); // calls recursive() again w/o a reported value
}
}; // end of recursive()
recursive(ns.length - 1); // starts recursive rounding over the ns char array (arg is the last index of ns)
if (opts.return == "number") return parseFloat(ns.join('')); // returns float number
else if (opts.return == "string") return ns.join(''); // returns float number as string
}
} //
How it works:
We first turn the provided float
value into a string
before splitting it into an array
of char
using the String.split('')
instruction.
Then we will call the recursive()
function with the last index of the array of chars as argument, to iterate through that array from last index to the precision index while rounding the value.
Arguments explanation:
There is a total of 3 arguments which allow different functionnalities.
n
:
the value to be rounded (number
or string
).precision
: [default = 0]int
which represent the amount of decimals we want to round the provided number to.precision == 0
: value returned will be the same as using the Math.round()
methodprecision > 0
: precision will be defined from the float separator index + precision valueprecision < 0
: precision will be defined from the index of the last number - precision valueopts
: [default = {return: 'number'}] object
with a unique property called return
which take a string value options are 'number'
or 'string'
. 2nd and 3rd arguments are optionnals
Usage and examples:
using a float value
let n = 20.336099982261654;
let r = roundFloatR(n); // r = 20
r = roundFloatR(n, 2); // r = 20.34
r = roundFloatR(n, 6); // r = 20.3361
r = roundFloatR(n, 6, {return: 'string'}); // r = "20.336100"
// negative precision
r = roundFloatR(n, -2); // r = 20.3360999822617
using a string value
let n = '20.48490002346038';
let r = roundFloatR(n); // r = 20
r = roundFloatR(n, 2); // r = 20.49
r = roundFloatR(n, 6); // r = 20.4849
r = roundFloatR(n, 6, {return: 'string'}); // r = "20.484900"
// negative precision
r = roundFloatR(n, -10); // r = 20.4849
What about performance ?
Most of the time it will convert the provided value in under .3
ms. (measured with performance.now()
)
What is not supported and possible issues:
precision
value that exceeds the provided number length or its float separator index may cause unexpected results as these cases are not handled yet.n
parameter doesn't match what is currently asked.I think below function can help
function roundOff(value,round) {
return (parseInt(value * (10 ** (round + 1))) - parseInt(value * (10 ** round)) * 10) > 4 ? (((parseFloat(parseInt((value + parseFloat(1 / (10 ** round))) * (10 ** round))))) / (10 ** round)) : (parseFloat(parseInt(value * (10 ** round))) / ( 10 ** round));
}
usage : roundOff(600.23458,2);
will return 600.23