JavaScript数学,舍入到小数点后两位

JavaScript math, round to two decimal places

本问题已经有最佳答案,请猛点这里访问。

我有以下javascript语法:

1
var discount = Math.round(100 - (price / listprice) * 100);

这是一个整数。如何返回两位小数的结果?


注-如果3位精度很重要,请参见编辑4。

1
var discount = (price / listprice).toFixed(2);

tofixed将根据超过2位小数的值向上或向下取整。

示例:http://jsfiddle.net/calder12/tv9hy/

文档:https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/number/tofixed

编辑-正如其他人所提到的,它将结果转换为字符串。为了避免这种情况:

1
var discount = +((price / listprice).toFixed(2));

编辑2-正如注释中提到的,此函数在某些精度上失败,例如,在1.005的情况下,它将返回1.00而不是1.01。如果准确到这个程度是很重要的,我已经找到了这个答案:https://stackoverflow.com/a/326605063/1726511,这似乎对我尝试过的所有测试都很有效。

但是需要做一个小的修改,上面链接的答案中的函数在四舍五入为1时返回整数,例如99.004将返回99,而不是99.00,这对于显示价格并不理想。

编辑3-似乎有固定在实际返回仍然搞砸了一些数字,这最后的编辑似乎工作。太多的修改!

1
2
3
4
5
6
7
8
9
10
11
12
   var discount = roundTo((price / listprice), 2);

   function roundTo(n, digits) {
     if (digits === undefined) {
       digits = 0;
     }

     var multiplicator = Math.pow(10, digits);
     n = parseFloat((n * multiplicator).toFixed(11));
     var test =(Math.round(n) / multiplicator);
     return +(test.toFixed(digits));
   }

请参见下面的小提琴示例:https://jsfiddle.net/calder12/3lbhfy5s/

编辑4-你们杀了我。"编辑3"在负数上失败,但没有深入了解为什么在进行舍入之前将负数变为正数比较容易,然后在返回结果之前将其变回原处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function roundTo(n, digits) {
    var negative = false;
    if (digits === undefined) {
        digits = 0;
    }
        if( n < 0) {
        negative = true;
      n = n * -1;
    }
    var multiplicator = Math.pow(10, digits);
    n = parseFloat((n * multiplicator).toFixed(11));
    n = (Math.round(n) / multiplicator).toFixed(2);
    if( negative ) {    
        n = (n * -1).toFixed(2);
    }
    return n;
}

小提琴:https://jsfiddle.net/3lbhfy5s/79/


如果使用一元加号将字符串转换为MDN中记录的数字。

例如:+discount.toFixed(2)


函数math.round()和.tofixed()旨在四舍五入到最接近的整数。在处理小数和使用math.round()的"乘除"方法或.tofixed()的参数时,会得到错误的结果。例如,如果您尝试使用math.round(1.005*100)/100对1.005进行取整,那么您将得到1的结果,并使用.tofixed(2)对1.00进行取整,而不是得到1.01的正确答案。

您可以使用以下方法来解决此问题:

1
Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2');

加上.tofixed(2)得到你想要的两个小数位。

1
Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2').toFixed(2);

您可以创建一个函数来处理舍入:

1
2
3
function round(value, decimals) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}

例子:网址:https://jsfiddle.net/k5tpq3pd/36/

交替的

您可以使用原型向数字添加一个圆函数。我不建议在这里添加.tofixed(),因为它将返回一个字符串而不是数字。

1
2
3
Number.prototype.round = function(decimals) {
    return Number((Math.round(this +"e" + decimals)  +"e-" + decimals));
}

像这样使用:

1
2
3
var numberToRound = 100 - (price / listprice) * 100;
numberToRound.round(2);
numberToRound.round(2).toFixed(2); //Converts it to string with two decimals

例子网址:https://jsfiddle.net/k5tpq3pd/35/

来源:http://www.jacklmoore.com/notes/rounding-in-javascript/


要得到两个小数的结果,可以这样做:

1
var discount = Math.round((100 - (price / listprice) * 100) * 100) / 100;

将要舍入的值乘以100以保留前两位数字,然后除以100以得到实际结果。


尝试使用discount.toFixed(2);


我找到的最好和简单的解决方案是

1
2
3
4
function round(value, decimals) {
 return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}  
round(1.005, 2); // 1.01


我认为我看到的最好的方法是用10乘以数字的幂,然后做一个数学四舍五入,最后除以10得到数字的幂。下面是我在typescript中使用的一个简单函数:

1
2
3
4
5
6
function roundToXDigits(value: number, digits: number) {
    value = value * Math.pow(10, digits);
    value = Math.round(value);
    value = value / Math.pow(10, digits);
    return value;
}

或纯JavaScript:

1
2
3
4
5
6
7
8
9
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;
}


对已接受答案的微小变化。toFixed(2)返回一个字符串,您将始终得到两个小数位。这些可能是零。如果要抑制最终零,只需执行以下操作:

1
var discount = + ((price / listprice).toFixed(2));

编辑:我刚刚发现了火狐35.0.1中的一个bug,这意味着上面给出的NaN可能有一些值。我把代码改成了

1
var discount = Math.round(price / listprice * 100) / 100;

这会给出最多两位小数的数字。如果你想要三个,你可以乘以1000,依此类推。op总是需要两个小数位,但是如果在firefox中tofixed()被破坏,它需要首先修复。查看https://bugzilla.mozilla.org/show_bug.cgi?ID=1134388


最快的方式-比tofixed()快:

两小数

1
2
x      = .123456
result = Math.round(x * 100) / 100  // result .12

三小数

1
2
x      = .123456
result = Math.round(x * 1000) / 1000      // result .123


1
2
3
4
5
6
7
    function round(num,dec)
    {
      num = Math.round(num+'e'+dec)
      return Number(num+'e-'+dec)
    }
      //Round to a decimal of your choosing:
    round(1.3453,2)


1
2
3
4
function discoverOriginalPrice(discountedPrice, salePercentage) {
  var originalPrice = discountedPrice / (1 - (salePercentage * .01));
  return +originalPrice.toFixed(2);
}


要处理小数位数的舍入,一个带有两行代码的函数就足以满足大多数需要。下面是一些示例代码。

1
2
3
4
5
6
7
8
9
    var testNum = 134.9567654;
    var decPl = 2;
    var testRes = roundDec(testNum,decPl);  
    alert (testNum + ' rounded to ' + decPl + ' decimal places is ' + testRes);

    function roundDec(nbr,dec_places){
        var mult = Math.pow(10,dec_places);
        return Math.round(nbr * mult) / mult;
    }

这是一个有效的例子

1
2
var value=200.2365455;
result=Math.round(value*100)/100    //result will be 200.24