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

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个回答

9
parseFloat("1.555").toFixed(2); // 返回1.55而不是1.56。
1.55是绝对正确的结果,因为计算机中不存在1.555的精确表示。如果读取1.555,则会四舍五入到最接近的可能值=1.55499999999999994(64位浮点数)。通过toFixed(2)将此数字四舍五入结果为1.55。
如果输入为1.55499999999999,则此处提供的所有其他函数都会给出错误结果。
解决方案:在扫描之前在数字前添加数字“5”,以向上舍入(更准确地说,是远离0)该数字。只有在数字真正为浮点数(具有小数点)时才执行此操作。
parseFloat("1.555"+"5").toFixed(2); // Returns 1.56

8
一个简单通用的解决方案

const round = (n, dp) => {
  const h = +('1'.padEnd(dp + 1, '0')) // 10 or 100 or 1000 or etc
  return Math.round(n * h) / h
}

console.log('round(2.3454, 3)', round(2.3454, 3)) // 2.345
console.log('round(2.3456, 3)', round(2.3456, 3)) // 2.346
console.log('round(2.3456, 2)', round(2.3456, 2)) // 2.35

或者只需使用Lodash round,它具有相同的签名 - 例如,_.round(2.3456, 2)


7
如果您想要向上取整,一个简单的解决方案是使用 Lodash 的 ceil 函数...
_.round(6.001, 2)

给出6

_.ceil(6.001, 2);

提供了6.01

_.ceil(37.4929, 2);

给出了37.5

_.round(37.4929, 2);

给出 37.49


3
引入新的依赖项仅仅是为了四舍五入而言毫无意义。 - Dmytro Medvid
考虑到lodash提供的功能,你的JavaScript项目还没有使用lodash,这真是太有趣了... - Pavithran Ravichandiran
1
已经有本地实现的情况下,我并不是说lodash(underscore)没有用处,我只是想说,如果你只需要四舍五入,那么使用lodash就没有意义了。当然,如果你喜欢并且每天都在使用它,并且整个项目都充满了lodash调用,那么使用它就是有意义的。 - Dmytro Medvid

7

根据所选答案和同一问题上的顶部评论

Math.round((num + 0.00001) * 100) / 100

这对这两个例子都有效:

Math.round((1.005 + 0.00001) * 100) / 100

Math.round((1.0049 + 0.00001) * 100) / 100

5
此函数在1.004999处失效。 - Wiimm

6

这对我很有用(TypeScript):

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;
}

样例输出

Rounded 18.339840000000436 to 18.34
Rounded 52.48283999999984 to 52.48
Rounded 57.24612000000036 to 57.25
Rounded 23.068320000000142 to 23.07
Rounded 7.792980000000398 to 7.79
Rounded 31.54157999999981 to 31.54
Rounded 36.79686000000004 to 36.8
Rounded 34.723080000000124 to 34.72
Rounded 8.4375 to 8.44
Rounded 15.666960000000074 to 15.67
Rounded 29.531279999999924 to 29.53
Rounded 8.277420000000006 to 8.28

6

另一种方法是:

number = 16.6666666;
console.log(parseFloat(number.toFixed(2)));
"16.67"

number = 16.6;
console.log(parseFloat(number.toFixed(2)));
"16.6"

number = 16;
console.log(parseFloat(number.toFixed(2)));
"16"

.toFixed(2) 会返回一个字符串,保留两位小数,但可能包含尾随的零。使用 parseFloat() 函数可以去掉这些尾随的零。


6

数学中的 floor 和 round 定义:

Enter image description here

带领我们到

let round= x=> ( x+0.005 - (x+0.005)%0.01 +'' ).replace(/(\...)(.*)/,'$1');

// for a case like 1.384 we need to use a regexp to get only 2 digits after the dot
// and cut off machine-error (epsilon)

console.log(round(10));
console.log(round(1.7777777));
console.log(round(1.7747777));
console.log(round(1.384));


6
问题是保留两位小数。
让我们不要把这变得复杂化,修改原型链等等。
下面是一行解决方案。

let round2dec = num => Math.round(num * 100) / 100;

console.log(round2dec(1.77));
console.log(round2dec(1.774));
console.log(round2dec(1.777));
console.log(round2dec(10));


6

一个简单的通用取整函数可以按照以下步骤执行:

步骤如下:

  1. 使用Math.pow(10,places)将数字乘以(10的小数位数次方)。
  2. 使用Math.Round将结果四舍五入为整数。
  3. 将结果再除以(10的小数位数次方)Math.pow(10,places)

示例:

要将数字1.2375取三位小数:

  1. 1.2375 * (10^3) ==> 1.2375 * 1000 = 1237.5
  2. 四舍五入得到整数 ==> 1238
  3. 将1238除以(10^3) ==> 1238 / 1000 = 1.238

(注意: 10^3表示Math.pow(10,3))。

 function numberRoundDecimal(v,n) {
 return Math.round((v+Number.EPSILON)*Math.pow(10,n))/Math.pow(10,n)}


// ------- tests --------
console.log(numberRoundDecimal(-0.024641163062896567,3))  // -0.025
console.log(numberRoundDecimal(0.9993360575508052,3))     // 0.999
console.log(numberRoundDecimal(1.0020739645577939,3))     // 1.002
console.log(numberRoundDecimal(0.975,0))                  // 1
console.log(numberRoundDecimal(0.975,1))                  // 1
console.log(numberRoundDecimal(0.975,2))                  // 0.98
console.log(numberRoundDecimal(1.005,2))                  // 1.01


6

我已阅读所有答案,类似问题的答案和大多数"好"解决方案的复杂性并未令我满意。我不想放置一个巨大的圆形函数集,或者是一个小的但在科学计数法上失败的函数集。因此,我想出了这个函数。它可能会对处于我的情况下的某些人有所帮助。

function round(num, dec) {
   const [sv, ev] = num.toString().split('e');
   return Number(Number(Math.round(parseFloat(sv + 'e' + dec)) + 'e-' + dec) + 'e' + (ev || 0));
}

我没有进行任何性能测试,因为我只会调用它来更新我的应用程序的用户界面。这个函数在快速测试中给出了以下结果:

// 1/3563143 = 2.806510993243886e-7
round(1/3563143, 2)  // returns `2.81e-7`

round(1.31645, 4)    // returns 1.3165

round(-17.3954, 2)   // returns -17.4

这对我来说已经足够了。


round(4.45, 0) = 4 expected 5 - Alex
@Alex 我认为你进行了双重舍入。4.45 舍入后应该是 4,而不是 5。 - Nathan Wailes
那些测试用例都很简单。那么其他答案和评论中提到的 1.015 和其他有问题的数字呢? - Peter Mortensen
@Peter,它四舍五入得好吗?你检查过了吗?有什么问题吗? - superkeci

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