117

在 JavaScript 中,将数字四舍五入到 N 位小数的典型方法是:

function roundNumber(num, dec) {
  return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
}

function roundNumber(num, dec) {
  return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
}

console.log(roundNumber(0.1 + 0.2, 2));
console.log(roundNumber(2.1234, 2));

但是,这种方法最多会舍入到N 个小数位,而我希望总是舍入到 N 个小数位。例如,“2.0”将四舍五入为“2”。

有任何想法吗?

4

9 回答 9

266

我认为这里给出了一个更简单的方法,并且是Number.toFixed()已经在 J​​avaScript 中实现的方法。

简单地写:

var myNumber = 2;

myNumber.toFixed(2); //returns "2.00"
myNumber.toFixed(1); //returns "2.0"

ETC...

于 2011-08-18T07:08:50.193 回答
52

我找到了一个方法。这是 Christoph 的修复代码:

function toFixed(value, precision) {
    var precision = precision || 0,
        power = Math.pow(10, precision),
        absValue = Math.abs(Math.round(value * power)),
        result = (value < 0 ? '-' : '') + String(Math.floor(absValue / power));

    if (precision > 0) {
        var fraction = String(absValue % power),
            padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');
        result += '.' + padding + fraction;
    }
    return result;
}

如果您对我添加“+ 1”的原因感到好奇,请阅读此处使用数组构造函数重复字符的详细信息。

于 2010-05-25T23:34:50.660 回答
26

这不是一个四舍五入的问题,这是一个显示问题。一个数字不包含有关有效数字的信息;值 2 与 2.0000000000000 相同。当您将四舍五入的值转换为字符串时,您可以使其显示一定数量的数字。

您可以在数字后添加零,例如:

var s = number.toString();
if (s.indexOf('.') == -1) s += '.';
while (s.length < s.indexOf('.') + 4) s += '0';

(请注意,这假设客户端的区域设置使用句点作为小数分隔符,代码需要更多工作才能用于其他设置。)

于 2010-02-08T11:27:23.640 回答
18

做事总是有更好的方法。

var number = 51.93999999999761;

我想得到四位数的精度:51.94

做就是了:

number.toPrecision(4);

结果将是:51.94

于 2012-11-16T17:04:05.300 回答
6

类 PHP 舍入方法

下面的代码可用于将您自己的 Math.round 版本添加到您自己的名称空间中,该名称空间采用精度参数。与上面示例中的小数舍入不同,这不执行字符串之间的转换,并且精度参数的工作方式与 PHP 和 Excel 相同,正 1 将舍入到小数点后 1 位,-1 将舍入到十位。

var myNamespace = {};
myNamespace.round = function(number, precision) {
    var factor = Math.pow(10, precision);
    var tempNumber = number * factor;
    var roundedTempNumber = Math.round(tempNumber);
    return roundedTempNumber / factor;
};

myNamespace.round(1234.5678, 1); // 1234.6
myNamespace.round(1234.5678, -1); // 1230

来自Math.round() 的 Mozilla 开发人员参考

于 2016-08-16T09:02:50.733 回答
5

这适用于四舍五入到 N 位(如果您只想截断到 N 位,请删除 Math.round 调用并使用 Math.trunc ):

function roundN(value, digits) {
   var tenToN = 10 ** digits;
   return /*Math.trunc*/(Math.round(value * tenToN)) / tenToN;
}

过去我在编写数据操作 E-Slate 组件时不得不求助于 Java 的这种逻辑。那是因为我发现多次将 0.1 加到 0 中,你最终会得到一些意想不到的长小数部分(这是由于浮点运算)。

格式编号处的用户注释始终显示 2 个小数位称为此技术缩放。

有人提到有些情况没有按预期进行,在http://www.jacklmoore.com/notes/rounding-in-javascript/建议改为:

function round(value, decimals) {
  return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}
于 2019-06-17T13:38:52.657 回答
2

希望工作代码(没有做太多测试):

function toFixed(value, precision) {
    var precision = precision || 0,
        neg = value < 0,
        power = Math.pow(10, precision),
        value = Math.round(value * power),
        integral = String((neg ? Math.ceil : Math.floor)(value / power)),
        fraction = String((neg ? -value : value) % power),
        padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');

    return precision ? integral + '.' +  padding + fraction : integral;
}
于 2010-02-08T11:48:37.773 回答
2

我认为以下功能可以提供帮助

function roundOff(value,round) {
   return (parseInt(value * (10 ** (round + 1))) - parseInt(value * (10 ** round)) * 10) > 4 ? (((parseFloat(parseInt((value + parseFloat(1 / (10 ** round))) * (10 ** round))))) / (10 ** round)) : (parseFloat(parseInt(value * (10 ** round))) / ( 10 ** round));
}

用法:roundOff(600.23458,2);将返回600.23

于 2017-09-08T19:24:19.140 回答
-2

如果您并不真正关心舍入,只需添加一个 toFixed(x) ,然后在必要时删除尾随的 0 和点。这不是一个快速的解决方案。

function format(value, decimals) {
    if (value) {
        value = value.toFixed(decimals);            
    } else {
        value = "0";
    }
    if (value.indexOf(".") < 0) { value += "."; }
    var dotIdx = value.indexOf(".");
    while (value.length - dotIdx <= decimals) { value += "0"; } // add 0's

    return value;
}
于 2014-04-16T07:57:31.187 回答