488

我有以下 JavaScript 语法:

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

这四舍五入为整数。如何返回两位小数的结果?

4

12 回答 12

899

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

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

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

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

编辑 2 - 正如评论中还提到的,此函数在某些精度上失败,例如,在 1.005 的情况下,它将返回 1.00 而不是 1.01。如果这种程度的准确性很重要,我找到了这个答案:https ://stackoverflow.com/a/32605063/1726511这似乎适用于我尝试过的所有测试。

虽然需要进行一个小的修改,上面链接的答案中的函数在四舍五入时会返回整数,因此例如 99.004 将返回 99 而不是 99.00,这不适合显示价格。

编辑 3 - 似乎在实际返回时 toFixed 仍然搞砸了一些数字,这个最终编辑似乎有效。哎呀,这么多返工!

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 在负数上失败,没有深入研究为什么在进行舍入之前将负数变为正数更容易,然后在返回结果之前将其返回。

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(digits);
    if (negative) {
        n = (n * -1).toFixed(digits);
    }
    return n;
}

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

于 2013-04-02T11:19:49.260 回答
152

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

例如:+discount.toFixed(2)

于 2014-04-10T01:32:52.937 回答
54

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

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

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

添加 .toFixed(2) 以获得您想要的两位小数。

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

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

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

示例: https ://jsfiddle.net/k5tpq3pd/36/

另类

您可以使用原型向 Number 添加舍入函数。我不建议在此处添加 .toFixed() ,因为它会返回字符串而不是数字。

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

并像这样使用它:

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/

于 2015-03-17T13:58:46.413 回答
36

要获得两位小数的结果,您可以这样做:

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

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

于 2013-04-02T11:33:19.887 回答
31

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

function round(value, decimals) {
 return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}   
round(1.005, 2); // 1.01
于 2017-02-21T13:22:01.160 回答
23

尝试使用discount.toFixed(2);

于 2013-04-02T11:22:24.717 回答
20

我认为我见过的最好的方法是乘以 10 的位数的幂,然后做一个 Math.round,最后除以 10 的位数。这是我在打字稿中使用的一个简单函数:

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:

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;
}
于 2017-04-21T02:14:39.223 回答
10

接受答案的一个小变化。 toFixed(2)返回一个字符串,你总是会得到两位小数。这些可能是零。如果您想抑制最后的零,只需执行以下操作:

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

编辑:我刚刚发现了 Firefox 35.0.1 中的一个错误,这意味着上面可能会给 NaN 一些值。
我已将代码更改为

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

这给出了最多两位小数的数字。如果你想要三个,你可以乘除以 1000,以此类推。
OP 始终需要两位小数,但如果 toFixed() 在 Firefox 中被破坏,则需要先修复。
https://bugzilla.mozilla.org/show_bug.cgi?id=1134388

于 2014-11-30T16:23:12.403 回答
8

最快的方式- 比 toFixed() 更快:

两个小数

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

三个小数

x      = .123456
result = Math.round(x * 1000) / 1000      // result .123
于 2016-02-13T00:59:10.520 回答
2
    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)
于 2017-03-25T04:56:48.677 回答
0

这是一个工作示例

var value=200.2365455;
result=Math.round(value*100)/100    //result will be 200.24
于 2016-06-13T14:33:36.490 回答
0

要处理四舍五入到任何小数位,一个具有 2 行代码的函数就足以满足大多数需求。这是一些可以使用的示例代码。



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

于 2016-09-05T16:02:01.060 回答