Round to at most 2 decimal places (only if necessa

2018-12-31 01:03发布

I'd like to round at most 2 decimal places, but only if necessary.

Input:

10
1.7777777
9.1

Output:

10
1.78
9.1

How can I do this in JavaScript?

30条回答
长期被迫恋爱
2楼-- · 2018-12-31 01:03

In general, rounding is done by scaling: round(num / p) * p

Using the exponential notation handles rounding of +ve numbers, correctly. However, this method fails to round -ve edge cases correctly.

function round(num, precision = 2) {
	var scaled = Math.round(num + "e" + precision);
	return Number(scaled + "e" + -precision);
}

// testing some edge cases
console.log( round(1.005, 2) );  // 1.01 correct
console.log( round(2.175, 2) );  // 2.18 correct
console.log( round(5.015, 2) );  // 5.02 correct

console.log( round(-1.005, 2) );  // -1    wrong
console.log( round(-2.175, 2) );  // -2.17 wrong
console.log( round(-5.015, 2) );  // -5.01 wrong

Here, also is one function I wrote to do arithmetic rounding correctly. You can test it yourself.

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct

查看更多
无与为乐者.
3楼-- · 2018-12-31 01:03

For me Math.round() was not giving correct answer. I found toFixed(2) works better. Below are examples of both:

console.log(Math.round(43000 / 80000) * 100); // wrong answer

console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer

查看更多
只若初见
4楼-- · 2018-12-31 01:03

Try this light weight solution:

function round(x, digits){
  return parseFloat(x.toFixed(digits))
}

 round(1.222,  2) ;
 // 1.22
 round(1.222, 10) ;
 // 1.222
查看更多
孤独总比滥情好
5楼-- · 2018-12-31 01:04

It may work for you,

Math.round(num * 100)/100;

to know the difference between toFixed and round. You can have a look at Math.round(num) vs num.toFixed(0) and browser inconsistencies.

查看更多
孤独寂梦人
6楼-- · 2018-12-31 01:06

Easiest way:

+num.toFixed(2)

It converts it to a string, and then back into an integer / float.

查看更多
一个人的天荒地老
7楼-- · 2018-12-31 01:06

If you happen to already be using the d3 library, they have a powerful number formatting library: https://github.com/mbostock/d3/wiki/Formatting

Rounding specifically is here: https://github.com/mbostock/d3/wiki/Formatting#d3_round

In your case, the answer is:

> d3.round(1.777777, 2)
1.78
> d3.round(1.7, 2)
1.7
> d3.round(1, 2)
1
查看更多
登录 后发表回答