【问题标题】:How to format numbers? [duplicate]如何格式化数字? [复制]
【发布时间】:2011-08-09 12:38:12
【问题描述】:

我想使用 JavaScript 格式化数字。

例如:

10     => 10.00
100    => 100.00
1000   => 1,000.00
10000  => 10,000.00
100000 => 100,000.00

【问题讨论】:

  • 您确定您的意思是“1,00,000”吗?也许“100,000”。
  • @LightnessRacesinOrbit,有趣的事实 - 在印度,他们将数字分组,例如12,34,567.89
  • @Nils @BoundaryImposition: (1234567.89).toLocaleString('hi-IN') 是“12,34,567.89”

标签: javascript


【解决方案1】:
 function formatNumber1(number) {
  var comma = ',',
      string = Math.max(0, number).toFixed(0),
      length = string.length,
      end = /^\d{4,}$/.test(string) ? length % 3 : 0;
  return (end ? string.slice(0, end) + comma : '') + string.slice(end).replace(/(\d{3})(?=\d)/g, '$1' + comma);
 }

 function formatNumber2(number) {
  return Math.max(0, number).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g, ',');
 }

来源:http://jsperf.com/number-format

【讨论】:

  • 但是使用 .toFixed(2) 我不会得到 10000 和 100000 的结果。
  • 我刚刚更新了我的答案
  • 这并不能真正回答问题。这些函数对数字进行四舍五入,它们不添加两位小数。
  • 这些解决方案都不适用于负数
【解决方案2】:

使用 Number 函数toFixed 和此函数添加逗号。

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

addCommas(r); // 10,000.00

http://www.mredkj.com/javascript/numberFormat.html

【讨论】:

  • 但是使用 .toFixed(2) 我不会得到 10000 和 100000 的结果为 10,000.00 和 1,00,000.00
  • 如果你从其他地方复制代码,提供参考链接会很好:mredkj.com/javascript/numberFormat.html
  • @oezi - 当然,当然。 @Chris - 已更新以显示逗号格式。
  • 感谢您的回答:)
【解决方案3】:

使用

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
【解决方案4】:

This 是一篇关于您的问题的文章。添加千位分隔符不是内置在 JavaScript 中的,因此您必须像这样编写自己的函数(示例取自链接页面):

function addSeperator(nStr){
  nStr += '';
  x = nStr.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;
}

【讨论】:

    【解决方案5】:

    我认为这个jQuery-numberformatter 可以解决你的问题。

    当然,这是假设您在项目中使用 jQuery 没有问题。请注意,该功能与blur 事件相关联。

    $("#salary").blur(function(){
          $(this).parseNumber({format:"#,###.00", locale:"us"});
          $(this).formatNumber({format:"#,###.00", locale:"us"});
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    
    <script src="https://cdn.jsdelivr.net/gh/timdown/jshashtable/hashtable.js"></script>
    
    <script src="https://cdn.jsdelivr.net/gh/hardhub/jquery-numberformatter/src/jquery.numberformatter.js"></script>
    
    <input type="text" id="salary">

    【讨论】:

    • 谷歌代码was shutdown on 2016-01-15。您可能需要更新损坏的链接,“404。这是一个错误。”(Google Code 上的许多项目已移至 GitHub)。
    • 谢谢@PeterMortensen!更新了链接!
    • 为什么投反对票?需要解释一下吗?
    • 更新了代码sn-p,方便查看结果和作品上的脚本。
    【解决方案6】:

    如果您使用 jQuery,则可以使用 formatnumber format 插件。

    【讨论】:

      【解决方案7】:

      这将为您提供逗号分隔的值,并将固定符号添加到末尾。

          nStr="1000";
          nStr += '';
          x = nStr.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');
          }
          commaSeperated = x1 + x2 + ".00";
          alert(commaSeperated);
      

      Source

      【讨论】:

        【解决方案8】:

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

        根据您要达到的目标,您可能需要舍入或不舍入,因此这里有两个版本跨越该鸿沟。

        首先是四舍五入。

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

        这个版本仍然分离小数,但使用与以前不同的方法。 w|0 部分删除小数点。有关这方面的更多信息,这是good answer。然后留下剩余的整数,将其存储在 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: '');
        };
        

        您可以在下面的 sn-p 中编辑数字来测试自己。

        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: '');
        };
        
        var dp;
        var createInput = function(v){
          var inp = jQuery('<input class="input" />').val(v);
          var eql = jQuery('<span>&nbsp;=&nbsp;</span>');
          var out = jQuery('<div class="output" />').css('display', 'inline-block');
          var row = jQuery('<div class="row" />');
          row.append(inp).append(eql).append(out);
          inp.keyup(function(){
            out.text(formatThousandsWithRounding(Number(inp.val()), Number(dp.val())));
          });
          inp.keyup();
          jQuery('body').append(row);
          return inp;
        };
        
        jQuery(function(){
          var numbers = [
            0, 99.999, -1000, -1000000, 1000000.42, -1000000.57, -1000000.999
          ], inputs = $();
          dp = jQuery('#dp');
          for ( var i=0; i<numbers.length; i++ ) {
            inputs = inputs.add(createInput(numbers[i]));
          }
          dp.on('input change', function(){
            inputs.keyup();
          });
        });
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <input id="dp" type="range" min="0" max="5" step="1" value="2" title="number of decimal places?" />

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

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

        这种方法避免了使用.split()RegExp(),但是,这两者相比起来都非常慢。虽然我从 Michael 关于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);
        };
        

        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);
        };
        
        var dp;
        var createInput = function(v){
          var inp = jQuery('<input class="input" />').val(v);
          var eql = jQuery('<span>&nbsp;=&nbsp;</span>');
          var out = jQuery('<div class="output" />').css('display', 'inline-block');
          var row = jQuery('<div class="row" />');
          row.append(inp).append(eql).append(out);
          inp.keyup(function(){
            out.text(formatThousandsNoRounding(Number(inp.val()), Number(dp.val())));
          });
          inp.keyup();
          jQuery('body').append(row);
          return inp;
        };
        
        jQuery(function(){
          var numbers = [
            0, 99.999, -1000, -1000000, 1000000.42, -1000000.57, -1000000.999
          ], inputs = $();
          dp = jQuery('#dp');
          for ( var i=0; i<numbers.length; i++ ) {
            inputs = inputs.add(createInput(numbers[i]));
          }
          dp.on('input change', function(){
            inputs.keyup();
          });
        });
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <input id="dp" type="range" min="0" max="5" step="1" value="2" title="number of decimal places?" />

        我很快会更新一个页面内的 sn-p 演示,但现在这里是一个小提琴:

        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 no.小数点):

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

        提琴手

        http://jsfiddle.net/XC3sS/

        【讨论】:

        • 这个有两个错误:当使用负数时,小数点会失败:-1000000.42变成-1,000,001.-42,并且因为floor方法而添加了一个。它还有另一个小数点错误:当我用dp=2 处理1000000.999 时,它变成1,000,000.100,所以3 个小数,我的数字没有四舍五入
        • @JasperV,非常好的点...为抬头欢呼。在我以前的任何用例中都没有发现这些问题。不过现在应该修复了。
        【解决方案9】:

        或者您可以使用sugar.js 库和format 方法:

        format( place = 0 , crowd = ',' , decimal = '.' ) 将数字格式化为可读字符串。如果地点未定义,将自动 确定地点。千是用于千的字符 分隔器。 decimal 是用于小数点的字符。

        例子:

        (56782).format() > "56,782"
        (56782).format(2) > "56,782.00"
        (4388.43).format(2, ' ') > "4 388.43"
        (4388.43).format(3, '.', ',') > "4.388,430"
        

        【讨论】:

          【解决方案10】:

          这大约是接受答案的 3 倍。它不创建数组,并避免在末尾创建整数的对象和字符串连接。如果您渲染大量值,这可能很有用,例如在表格中。

          function addThousandSeparators(number) {
              var whole, fraction
              var decIndex = number.lastIndexOf('.')
              if (decIndex > 0) {
                  whole = number.substr(0, decIndex)
                  fraction = number.substr(decIndex)
              } else {
                  whole = number
              }
              var rgx = /(\d+)(\d{3})/
              while (rgx.test(whole)) {
                  whole = whole.replace(rgx, '$1' + ',' + '$2')
              }
              return fraction ? whole + fraction : whole
          }
          

          【讨论】:

            【解决方案11】:

            让我也把我的解决方案放在这里。为了便于阅读,我对每一行进行了注释,并提供了一些示例,所以它可能看起来很大。

            function format(number) {
            
                var decimalSeparator = ".";
                var thousandSeparator = ",";
            
                // make sure we have a string
                var result = String(number);
            
                // split the number in the integer and decimals, if any
                var parts = result.split(decimalSeparator);
            
                // if we don't have decimals, add .00
                if (!parts[1]) {
                  parts[1] = "00";
                }
              
                // reverse the string (1719 becomes 9171)
                result = parts[0].split("").reverse().join("");
            
                // add thousand separator each 3 characters, except at the end of the string
                result = result.replace(/(\d{3}(?!$))/g, "$1" + thousandSeparator);
            
                // reverse back the integer and replace the original integer
                parts[0] = result.split("").reverse().join("");
            
                // recombine integer with decimals
                return parts.join(decimalSeparator);
            }
            
            document.write("10 => " + format(10) + "<br/>");
            document.write("100 => " + format(100) + "<br/>");
            document.write("1000 => " + format(1000) + "<br/>");
            document.write("10000 => " + format(10000) + "<br/>");
            document.write("100000 => " + format(100000) + "<br/>");
            document.write("100000.22 => " + format(100000.22) + "<br/>");

            【讨论】:

              【解决方案12】:

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

              Browser compatibility 在我第一次写这个答案时,toLocaleString() 上的扩展选项是有限的,但目前的状态看起来不错。 If you're using Node.js,你需要npm install intl 包。

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

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

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

              如果您来自与上述格式不同的文化,请edit此帖子并添加您的语言环境代码。


              1 你不应该这样做。
              2 显然不要这样做 for currency 与 @ 之类的东西987654335@ 除非您已转换为当地汇率。您不希望您的网站告诉人们价格是 300 日元,而实际上它是 300 美元。我见过真正的电子商务网站会犯这个错误。

              【讨论】:

              • 我想使用内置代码,这让我到了那里。语言环境选项是我愿意忍受的一个小问题。我认为这应该是公认的答案,因为它考虑了数字再现的语言环境细微差别。
              • 请注意toLocaleString 非常慢并且会在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 &lt; 100000; i++) { Number(number).toLocaleString('en-US', params); } console.log('on end RSS = ', process.memoryUsage().rss / 1024 / 1024);
              • var number = 1000; parseInt(number).toLocaleString();
              • @Tashi 你不需要parseInt(),甚至不需要number。这可以正常工作:(1000).toLocaleString()
              【解决方案13】:

              短解:

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

              【讨论】:

                【解决方案14】:

                在浏览器that supportECMAScript® 2016 Internationalization API Specification (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
                

                if (typeof Intl === "undefined" || !Intl.NumberFormat) {
                  console.log("This browser doesn't support Intl.NumberFormat");
                } else {
                  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
                }

                【讨论】:

                  【解决方案15】:

                  function numberWithCommas(x) {
                    x=String(x).toString();
                    var afterPoint = '';
                    if(x.indexOf('.') > 0)
                       afterPoint = x.substring(x.indexOf('.'),x.length);
                    x = Math.floor(x);
                    x=x.toString();
                    var lastThree = x.substring(x.length-3);
                    var otherNumbers = x.substring(0,x.length-3);
                    if(otherNumbers != '')
                        lastThree = ',' + lastThree;
                    return otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree + afterPoint;
                  }
                  
                  console.log(numberWithCommas(100000));
                  console.log(numberWithCommas(10000000));

                  输出

                  1,00,000
                  1,00,00,000

                  【讨论】:

                    【解决方案16】:

                    您可以考虑使用toLocaleString()

                    工作示例:

                    const number = 1234567890.123;
                    
                    console.log(number.toLocaleString('en-US')); // US format
                    
                    console.log(number.toLocaleString('en-IN')); // Indian format

                    在 Chrome v60 和 v88 中测试

                    来源:Number.prototype.toLocaleString() | MDN

                    【讨论】:

                    • 这是不正确的。 (重要)数字的限制来自于在 .toLocaleString(locale_id, options) 方法中提供一个选项对象。像这样:toLocaleString(ANY_LOCALE_ID, { maximumSignificantDigits: 3 })
                    • @BernoulliIT 感谢您提出这个问题,我已经更新了上面的答案
                    • 我没有看到答案的更正更新!?这个答案绝对是 OP 问题的最直接和优雅的解决方案。
                    • @BernoulliIT don't see a correcting update of the answer 是什么意思?您是否尝试过清除浏览器缓存?
                    • 你说得对,我记得 OP 的问题是关于限制位数(这是我在找到这篇文章时要寻找的地方),但事实并非如此。它在我的脑海中混淆了?
                    【解决方案17】:
                                    function formatThousands(n,dp,f) {
                                        // dp - decimal places
                                        // f - format >> 'us', 'eu'
                                        if (n == 0) {
                                            if(f == 'eu') {
                                                return "0," + "0".repeat(dp);   
                                            }
                                            return "0." + "0".repeat(dp);
                                        }
                    
                                        /* round to 2 decimal places */
                                        //n = Math.round( n * 100 ) / 100;
                                        var s = ''+(Math.floor(n)), d = n % 1, i = s.length, r = '';
                                        while ( (i -= 3) > 0 ) { r = ',' + s.substr(i, 3) + r; }
                                        var a = s.substr(0, i + 3) + r + (d ? '.' + Math.round((d+1) * Math.pow(10,dp)).toString().substr(1,dp) : '');
                                        /* change format from 20,000.00 to 20.000,00 */
                                        if (f == 'eu') {
                                            var b = a.toString().replace(".", "#");
                                            b = b.replace(",", ".");
                                            return b.replace("#", ",");
                                        }                   
                                        return a;
                                    }
                    

                    【讨论】:

                    • 与该问题的其他答案相比,此答案有什么不同?你能详细说明代码只回答的含义吗?
                    猜你喜欢
                    • 2013-04-08
                    • 2017-02-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-10-09
                    • 1970-01-01
                    • 2023-03-07
                    • 1970-01-01
                    • 2016-02-28
                    相关资源
                    最近更新 更多