如何将数字保留两位小数(如果必要)

4114

我希望最多保留两位小数,但只有必要时才这样做。

输入:

10
1.7777777
9.1

输出:

10
1.78
9.1

我该如何在JavaScript中实现这个?


1
const formattedNumber = Math.round(myNumber * 100) / 100; 将数字乘以100,然后四舍五入保留两位小数。 - Hamza Dahmoun
const formattedNumber = new Intl.NumberFormat('en', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(myNumber); const formattedNumberInNumber = parseFloat(formattedNumber);``` // #=> 1.28。[更多信息](https://dev59.com/anI-5IYBdhLWcg3wsKl4#1726662) - tinystone
92个回答

17

最简单的方法:

+num.toFixed(2)

它将数字转换为字符串,然后再转回整数/浮点数。


感谢您提供这个最简单的答案。但是,在+num中,'+'是什么意思?当十进制值以字符串形式出现时,它对我没有用。我尝试了以下代码:(num * 1).toFixed(2)。 - Ethan
@momo 将参数更改为 toFixed(), 设为 3。这样就是 +num.toFixed(3)。这样做的效果应该是正确的,1.005 被四舍五入为 1.00,等同于 1。 - bigpotato
2
@Edmund,它应该返回1.01,而不是1.00。 - mjs
这是user3711536的回答的复制,虽然它有一些(如果不够充分)的解释。 - Peter Mortensen

16

2022年,原生的、没有使用任何库,支持现代浏览器并且清晰易读。

function round(
  value,
  minimumFractionDigits,
  maximumFractionDigits
) {
  const formattedValue = value.toLocaleString('en', {
    useGrouping: false,
    minimumFractionDigits,
    maximumFractionDigits
  })
  return Number(formattedValue)
}

console.log(round(21.891, 2, 3)) // 21.891
console.log(round(1.8, 2)) // 1.8, if you need 1.80, remove the `Number` function. Return directly the `formattedValue`.
console.log(round(21.0001, 0, 1)) // 21
console.log(round(0.875, 3)) // 0.875


3
请运行此程序并查看结果是否与您所写的不同。 - Royi Namir
3
这段内容与IT有关。它的要点是什么? toLocaleString()应该做什么?它适用于数字1.015吗?为什么需要Number()?需要解释一下。根据帮助中心的说明:“...始终解释为什么你提出的解决方案是合适的以及它是如何工作的”。请通过编辑(更改)您的答案来回复,而不是在此处进行评论(不包括“Edit:”,“Update:”或类似内容 - 答案应该看起来像是今天写的)。 - Peter Mortensen

15

使用类似这样的内容 "parseFloat(parseFloat(value).toFixed(2))"

parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78 
parseFloat(parseFloat("10").toFixed(2))-->10 
parseFloat(parseFloat("9.1").toFixed(2))-->9.1

1
不要误解浮点表示本身的精度问题。如果你只是将其删除,然后再次转换为浮点数,那么你只是重新引入了同样的错误! - Ben McIntyre

14

这里是一个原型方法:

Number.prototype.round = function(places){
    places = Math.pow(10, places); 
    return Math.round(this * places)/places;
}

var yournum = 10.55555;
yournum = yournum.round(2);

13

为了避免处理许多0,请使用这个变体:

Math.round(num * 1e2) / 1e2

你是指什么意思的“不要处理太多0”?你能举个例子来解释一下吗?(但是请不要包含 “编辑:”,“更新:” 或类似的字眼——答案应该看起来像今天写的。) - Peter Mortensen
哦...“不用处理很多0”我只是为了强调e-表示法(指数表示法)而写的 B-) - Daniel De León

12

另一种方法是使用库。使用Lodash

const _ = require("lodash")
const roundedNumber = _.round(originalNumber, 2)

至少有五个之前的答案使用了 Lodash。 - Peter Mortensen
事实上,只有一个,我承认在我编写代码时没有看到它。 - Carlos Lombardi

11

与其像Brian Ustas建议的那样使用Math.round,我更喜欢使用Math.trunc方法来解决以下情况:

const twoDecimalRound = num => Math.round(num * 100) / 100;
const twoDecimalTrunc = num => Math.trunc(num * 100) / 100;
console.info(twoDecimalRound(79.996)); // Not desired output: 80;
console.info(twoDecimalTrunc(79.996)); // Desired output: 79.99;

10

更简单的 ES6 方法是

const round = (x, n) => 
  Number(parseFloat(Math.round(x * Math.pow(10, n)) / Math.pow(10, n)).toFixed(n));

这个模式也会返回所要求的精度。

例如:

round(44.7826456, 4)  // yields 44.7826
round(78.12, 4)       // yields 78.12

1
不幸的是,你的方法在末尾添加了不必要的零。我认为发布问题的解决方案应该得出 78.12 而不是 78.1200 - Marcin Wanago
@MarcinWanago 很好的发现,我在原帖的问题中忽略了那个。我已经更新了我的示例。谢谢。 - Adam A.

10
如果您已经在使用D3.js库,它们有一个功能强大的数字格式化库。具体来说,四舍五入是在D3 round中实现的。对于您的情况,答案为:
> d3.round(1.777777, 2)
1.78

> d3.round(1.7, 2)
1.7

> d3.round(1, 2)
1

2
看一下源代码,这只是@ustasb答案的一个通用版本,使用num * Math.pow(n)代替num * 100(但它绝对是一个整洁的一行代码;-) - svvac
但是有文档记录,并且作为一个库,我不需要检查浏览器兼容性的麻烦。 - Scott Stafford
使用 Math.pow(n) 可以使得 d3.round(12, -1) == 10。 - daviestar

9

我审查了本帖子的每个回答,这是我的看法:

const nbRounds = 7;
const round = (x, n=2) => {
  const precision = Math.pow(10, n)
  return Math.round((x+Number.EPSILON) * precision ) / precision;
}
let i = 0;
while( nbRounds > i++ ) {
  console.log("round(1.00083899, ",i,") > ", round(1.00083899, i))
  console.log("round(1.83999305, ",i,") > ", round(1.83999305, i))
}


1
你能解释一下你的看法吗?结论是什么?它适用于 1.015(以及其他在其他答案评论中提到的有问题的数字)吗?请通过编辑(更改)您的答案来回复,而不是在这里留言(不要添加“编辑:”,“更新:”或类似内容 - 答案应该看起来像是今天写的)。 - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接