如何格式化数字?

IT技术 javascript
2021-01-17 00:27:11

我想使用 JavaScript 格式化数字。

例如:

10     => 10.00
100    => 100.00
1000   => 1,000.00
10000  => 10,000.00
100000 => 100,000.00
6个回答

如果要使用内置代码,可以使用toLocaleString()with minimumFractionDigits

toLocaleString()当我第一次写这个答案时,扩展选项的浏览器兼容性是有限的,但当前状态看起来不错。如果您使用Node.js的,你需要npm installintl包。

var value = (100000).toLocaleString(
  undefined, // leave undefined to use the visitor's browser 
             // locale or a string like 'en-US' to override it.
  { minimumFractionDigits: 2 }
);
console.log(value);

数字格式因文化而异。除非您对输出进行字符串比较(您不应该这样做),否则礼貌的做法是选择undefined并让访问者的浏览器使用他们最熟悉的格式。

// Demonstrate selected international locales
var locales = [
  undefined,  // Your own browser
  'en-US',    // United States
  'de-DE',    // Germany
  'ru-RU',    // Russia
  'hi-IN',    // India
];
var n = 100000;
var opts = { minimumFractionDigits: 2 };
for (var i = 0; i < locales.length; i++) {
  console.log(locales[i], n.toLocaleString(locales[i], opts));
}

如果您来自与上述格式不同的文化,请编辑此帖子并添加您的区域设置代码。

变量数 = 1000;parseInt(number).toLocaleString();
2021-03-21 00:27:11
我想使用内置代码,这让我做到了。语言环境选项是我愿意忍受的一个小问题。我认为这应该是公认的答案,因为它考虑了数字再现的语言环境细微差别。
2021-03-25 00:27:11
请注意,toLocaleString它非常慢并且可能会在 Node 中泄漏内存!在 Node 10.16.3 上对此进行了测试:console.log('on start RSS = ', process.memoryUsage().rss / 1024 / 1024); const number = Math.random() * 10; const params = { minimumFractionDigits: 3, maximumFractionDigits: 3, useGrouping: false }; for (let i = 0; i < 100000; i++) { Number(number).toLocaleString('en-US', params); } console.log('on end RSS = ', process.memoryUsage().rss / 1024 / 1024);
2021-04-04 00:27:11
@Tashi 你不需要parseInt(),甚至不需要number这将正常工作:(1000).toLocaleString()
2021-04-07 00:27:11

简短的解决方案:

var n = 1234567890;
String(n).replace(/(.)(?=(\d{3})+$)/g,'$1,')
// "1,234,567,890"

利用

num = num.toFixed(2);

其中 2 是小数位数

编辑:

这是根据需要格式化数字的功能

function formatNumber(number)
{
    number = number.toFixed(2) + '';
    x = number.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

来源:www.mredkj.com

但是使用 .toFixed(2) 我不会得到 10000 和 100000 的结果为 10,000.00 和 1,00,000.00
2021-03-27 00:27:11

在浏览器支持ECMAScript®2016国际API规范(ECMA-402) 你可以用一个Intl.NumberFormat实例:

var nf = Intl.NumberFormat();
var x = 42000000;
console.log(nf.format(x)); // 42,000,000 in many locales
                           // 42.000.000 in many other locales

由于 JasperV 发现的错误 - 好点!— 我已经重写了我的旧代码。我想我只将它用于带有两位小数的正值。

根据您要实现的目标,您可能需要舍入与否,因此这里有两个版本跨越该鸿沟。

首先,四舍五入。

我介绍了该toFixed()方法,因为它可以更好地准确处理到特定小数位的舍入,并且得到很好的支持。然而,它确实减慢了速度。

此版本仍然分离小数,但使用与以前不同的方法。w|0部分删除小数。有关更多信息,这是一个很好的答案然后留下剩余的整数,将其存储k,然后从原始数字中再次减去它,留下小数本身。

此外,如果我们要考虑负数,我们需要 while 循环(跳过三位数)直到我们点击b这在处理负数时被计算为 1 以避免放入类似的东西-,100.00

循环的其余部分与之前相同。

function formatThousandsWithRounding(n, dp){
  var w = n.toFixed(dp), k = w|0, b = n < 0 ? 1 : 0,
      u = Math.abs(w-k), d = (''+u.toFixed(dp)).substr(2, dp),
      s = ''+k, i = s.length, r = '';
  while ( (i-=3) > b ) { r = ',' + s.substr(i, 3) + r; }
  return s.substr(0, i + 3) + r + (d ? '.'+d: '');
};

在下面的代码段中,您可以编辑数字来测试自己。

现在是另一个版本,没有四舍五入。

这采取了不同的路线并试图避免数学计算(因为这会引入舍入或舍入错误)。如果您不想四舍五入,那么您只是将事物作为字符串处理,即 1000.999 转换为两位小数将永远是 1000.99 而不是 1001.00。

这种方法避免使用.split()RegExp()但是,两者相比起来都非常慢。虽然我从迈克尔关于 的回答中学到了一些新东西toLocaleString,但我也惊讶地发现它是 - 在相当程度上 - 所有方法中最慢的方法(至少在 Firefox 和 Chrome 中;Mac OSX)。

使用lastIndexOf()我们找到可能存在的小数点,从那里开始,其他一切都几乎相同。在需要的地方用额外的 0 保存填充。此代码限制为小数点后 5 位。在我的测试中,这是更快的方法。

var formatThousandsNoRounding = function(n, dp){
  var e = '', s = e+n, l = s.length, b = n < 0 ? 1 : 0,
      i = s.lastIndexOf('.'), j = i == -1 ? l : i,
      r = e, d = s.substr(j+1, dp);
  while ( (j-=3) > b ) { r = ',' + s.substr(j, 3) + r; }
  return s.substr(0, j + 3) + r + 
    (dp ? '.' + d + ( d.length < dp ? 
        ('00000').substr(0, dp - d.length):e):e);
};

我很快就会更新一个页内片段演示,但现在这里有一个小提琴:

https://jsfiddle.net/bv2ort0a/2/



旧方法

为什么要为此使用 RegExp?- 当牙签可以使用时不要使用锤子,即使用字符串操作:

var formatThousands = function(n, dp){
  var s = ''+(Math.floor(n)), d = n % 1, i = s.length, r = '';
  while ( (i -= 3) > 0 ) { r = ',' + s.substr(i, 3) + r; }
  return s.substr(0, i + 3) + r + 
    (d ? '.' + Math.round(d * Math.pow(10, dp || 2)) : '');
};

走过

formatThousands( 1000000.42 );

首先去掉小数点:

s = '1000000', d = ~ 0.42

从字符串的末尾向后工作:

',' + '000'
',' + '000' + ',000'

通过添加剩余的前缀和小数后缀(四舍五入到dp小数点)来完成:

'1' + ',000,000' + '.42'

小提琴手

http://jsfiddle.net/XC3sS/

这个有 2 个错误:当使用负数时,它会因小数失败:-1000000.42变为-1,000,001.-42并添加一个,因为该floor方法。它还有另一个小数错误:当我1000000.999dp=2处理时变成1,000,000.1003 位小数,我的数字没有四舍五入
2021-03-21 00:27:11
@JasperV,很好的观点......为抬头加油。在我以前的任何用例中都没有发现这些问题。不过现在应该修复了。
2021-04-10 00:27:11