格式编号始终显示2个小数位


781

我想将数字格式化为始终显示2个小数位,并在适用的情况下四舍五入。

例子:

number     display
------     -------
1          1.00
1.341      1.34
1.345      1.35

我一直在使用这个:

parseFloat(num).toFixed(2);

但它显示11,而不是1.00


2
我的意思是,如果我输入1,它将不会显示数字为1.00,但是如果我输入1.345,那么它将显示1.35
Varada

1
我已将您的问题改写为我相信您正在寻找的内容。请检查以确保我正确理解了您。
德拉吉



Answers:


1114
(Math.round(num * 100) / 100).toFixed(2);

现场演示

请注意,它将四舍五入到小数点后两位,因此输入1.346将返回1.35


6
@Kooilnc:OP希望1显示为1.00,并1.341显示为1.34
德拉吉

49
无需使用round(),因为toFixed()对其进行了四舍五入。
米兰·巴布斯科夫2013年

27
toFixed()会对其进行四舍五入,但不要忘记它正在返回字符串...因此,此方法实际上仅对显示有用。如果要对舍入后的值执行进一步的数学计算,请不要使用toFixed()。
TWright,2015年

8
根据MDN,由于舍入错误,Math.round不会总是给出准确的结果。我用1.005进行了测试,应该四舍五入为1.01,但给出的是1.00。使用我的答案获得一致的准确性:stackoverflow.com/a/34796988/3549440
Nate

13
整个答案可以简化为(+num).toFixed(2)。它甚至保留了原始的舍入错误,请参阅Nate的答案
RobG

321
Number(1).toFixed(2);         // 1.00
Number(1.341).toFixed(2);     // 1.34
Number(1.345).toFixed(2);     // 1.34 NOTE: See andy's comment below.
Number(1.3450001).toFixed(2); // 1.35


1
最后一行是错误的。我在Chrome控制台中尝试了此操作,并且“ Number(1.365).toFixed(2)返回“ 1.37”
Andre

1
@ Andre,Chrome 29.0.1547.57给了我1.34表达的机会Number(1.345).toFixed(2)
Drew Noakes

1
toFixed 进行舍入,您几乎可以在每个测试编号上看到它。
andy

40
在完成之前不小心提交了最后一个评论.. 1.345就是不能精确存储在浮点数中的一个例子,所以我认为它没有按您期望的那样四舍五入的原因是它实际上被存储为一个数字小于1.345并向下舍入。如果用代替,(1.34500001).toFixed(2)那么您会看到它正确舍入到1.35
andy

94

如果,此答案将失败value = 1.005

作为更好的解决方案,可以通过使用指数表示法表示的数字来避免舍入问题:

Number(Math.round(1.005+'e2')+'e-2'); // 1.01

@Kon和原始作者建议的更干净的代码:

Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)

您可以toFixed()在末尾添加以保留小数点,例如:,1.00但请注意,它将以字符串形式返回。

Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces).toFixed(decimalPlaces)

信用:JavaScript中的舍入小数


13
令人惊讶的是,这里的其他所有人都没有看到toFixed存在四舍五入的问题。您的答案应该是被接受的。
Armfoot

1
刚刚测试,看看是否仍然如此。您对于Chrome版本59.0.3071.115仍然是正确的,您的解决方案将向上舍入为1.005(1.01),向下舍入为1.00499999(1.00)
Artistan'July 19''17,26

jsfiddle.net/Artistan/qq895bnp/28 在toFixed可以正常工作的时候有“时间”,但这是非常不一致的。:)
Artistan

parseFloat中的环绕数字是它的返回字符串
user889030 '17

1
这是一个可靠的答案。我可以想到几个改进:(1)VS Code(TypeScript文件)不喜欢Math.round()传递字符串。(2)动态设置小数位数(不硬编码为2)。(3)toFixed()似乎不必要。所以我想出的是Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)
Kon

23
var num = new Number(14.12);
console.log(num.toPrecision(2));//outputs 14
console.log(num.toPrecision(3));//outputs 14.1
console.log(num.toPrecision(4));//outputs 14.12
console.log(num.toPrecision(5));//outputs 14.120

如果您的数字可以是1.4、23.654和0,那将带来意想不到的结果,那么您将采用什么精度?
Shinzou

2
请注意,OP要求“四舍五入”toPrecision仅将数字格式化为特定的小数位数,只是省略多余的位数,而不舍入它们。当然,这也可能非常有用,但是了解差异非常重要。
波阿斯-恢复莫妮卡

1
根据Mozilla的说法,实际上toPrecision确实可以取整。测试:(20.55).toPrecision(3) "20.6"
James L.

2
如果要去除结尾的零,请在使用后将其强制转换为Number或Float toFixedconst formattedVal = Number(val.toFixed(2));不要使用toPrecision,因为在使用precision参数时它将计算非十进制数。
James L.

17

为了获得最精确的舍入,请创建以下函数:

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

并将其舍入到小数点后两位:

console.log("seeked to " + round(1.005, 2));
> 1.01

由于Razu文章,并MDN的Math.round参考


1
1.0049999999999998934怎么办?
4esn0k

1
它不会超过2 dp
Stephen Adelakun '16

1
经过jsfiddle.net/Artistan/qq895bnp测试,这是我所见过的唯一一致的方法。谢谢。
Artistan'7

16

对于现代浏览器,请使用toLocaleString

var num = 1.345;
num.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 });

将区域设置标签指定为控制小数点分隔符的第一个参数。对于点,请使用例如美国英语语言环境:

num.toLocaleString("en-US", { maximumFractionDigits: 2, minimumFractionDigits: 2 });

这使:

1.35

欧洲的大多数国家/地区使用逗号作为小数点分隔符,因此,例如,如果您使用瑞典语/瑞典语区域设置,则:

num.toLocaleString("sv-SE", { maximumFractionDigits: 2, minimumFractionDigits: 2 });

它会给:

1,35


不知道为什么不赞成这样做,对我来说似乎很好。如果您对此有任何疑问,请打算添加反对意见!
John Culviner19年

13

最简单的答案:

var num = 1.2353453;
num.toFixed(2); // 1.24

示例:http//jsfiddle.net/E2XU7/


11
好吧,toFixed已经在stackoverflow.com/a/13292833/218196中建议了。您的问题还提供哪些其他信息?
Felix Kling 2013年

那答案不包括圆形功能,我的答案包括寿。
macio.Jun 2013年

8
嗯?答案完全一样。拨打电话toFixed
Felix Kling 2013年

1
正确,相同的功能,但该答案的结果具有误导性,我只是通过表达圆形功能对其进行了纠正。
macio.Jun

问题指出:“ ...在适用情况下四舍五入”。您的答案不涉及四舍五入。
克里斯(Chris

12

四舍五入到N位的通用解决方案

function roundN(num,n){
  return parseFloat(Math.round(num * Math.pow(10, n)) /Math.pow(10,n)).toFixed(n);
}


console.log(roundN(1,2))
console.log(roundN(1.34,2))
console.log(roundN(1.35,2))
console.log(roundN(1.344,2))
console.log(roundN(1.345,2))
console.log(roundN(1.344,3))
console.log(roundN(1.345,3))
console.log(roundN(1.3444,3))
console.log(roundN(1.3455,3))

Output

1.00
1.34
1.35
1.34
1.35
1.344
1.345
1.344
1.346

1
此出价失败,某些数字接近0,roundN(-3.4028230607370965e+38,2)返回"-3.4028230607370965e+38"而不是预期的0.00
Ferrybig,

有趣的@Ferrybig我将测试您提到的数字并考虑解决方法,谢谢测试
PirateApp

1
请注意,前面提到的数字不应显示为零,而是一个巨大的数字,这只是我的大脑中的错误。但是它仍然不起作用,因为它仍然不显示2位小数
Ferrybig '19


9

如果您已经在使用jQuery,则可以考虑使用jQuery Number Format插件。

插件可以将格式化的数字作为字符串返回,您可以设置小数和千位分隔符,还可以选择显示的小数位数。

$.number( 123, 2 ); // Returns '123.00'

您还可以从GitHub获取jQuery Number Format


11
使用插件“仅具有固定长度的小数部分”是过大的。
Lashae

9
@Lashae,当然,如果这就是您想要做的。我发布了此信息,以防OP或其他任何人想要插件也提供的额外功能。
山姆·塞纳特

如果问题的发布者添加了jQuery标签;)
fullstacklife 2015年

7

你是这个意思吗?

function showAsFloat(num, n){
      return !isNaN(+num) ? (+num).toFixed(n || 2) : num;
}

document.querySelector('#result').textContent = 
    [
     'command                      | result',
     '-----------------------------------------------',
     'showAsFloat(1);              | ' + showAsFloat(1),
     'showAsFloat(1.314);          | ' + showAsFloat(1.314),
     'showAsFloat(\'notanumber\')    | ' + showAsFloat('notanumber'),
     'showAsFloat(\'23.44567\', 3)   | ' + showAsFloat('23.44567', 3),
     'showAsFloat(2456198, 5)      | ' + showAsFloat('2456198', 5),
     'showAsFloat(0);              | ' + showAsFloat(0)
    ].join('\n');
<pre id="result"></pre>



4

您在找地板吗?

var num = 1.42482;
var num2 = 1;
var fnum = Math.floor(num).toFixed(2);
var fnum2 = Math.floor(num2).toFixed(2);
alert(fnum + " and " + fnum2); //both values will be 1.00

4
我认为他不想舍入到最接近的整数。
德拉吉

是的,我从描述中不确定,但是我只是把它扔了出去,
以防

3
function currencyFormat (num) {
    return "$" + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

console.info(currencyFormat(2665));   // $2,665.00
console.info(currencyFormat(102665)); // $102,665.00

3

这也是一个通用函数,可以格式化为任意数量的小数位:

function numberFormat(val, decimalPlaces) {

    var multiplier = Math.pow(10, decimalPlaces);
    return (Math.round(val * multiplier) / multiplier).toFixed(decimalPlaces);
}

3

在需要特定格式的地方,您应该编写自己的例程或使用满足您需要的库函数。ECMAScript的基本功能通常不足以显示带格式的数字。

舍入和格式的完整说明在这里:http : //www.merlyn.demon.co.uk/js-round.htm#RiJ

通常,舍入和格式化仅应在输出之前作为最后一步执行。较早这样做可能会引入意想不到的大错误并破坏格式。


有时候我会摇头以深深地参与整个JS / Ecma平台。:(“需要特定格式的地方,您应该编写自己的例程或使用满足您需要的库函数。基本的ECMAScript功能通常不足以显示带格式的数字。”什么是asinine语句-并非您自己做的,但由于这一事实存在,只是难过找球,使用Javascript :)!
ChrisH

2

function number_format(string,decimals=2,decimal=',',thousands='.',pre='R$ ',pos=' Reais'){
  var numbers = string.toString().match(/\d+/g).join([]);
  numbers = numbers.padStart(decimals+1, "0");
  var splitNumbers = numbers.split("").reverse();
  var mask = '';
  splitNumbers.forEach(function(d,i){
    if (i == decimals) { mask = decimal + mask; }
    if (i>(decimals+1) && ((i-2)%(decimals+1))==0) { mask = thousands + mask; }
    mask = d + mask;
  });
  return pre + mask + pos;
}
var element = document.getElementById("format");
var money= number_format("10987654321",2,',','.');
element.innerHTML = money;
#format{
display:inline-block;
padding:10px;
border:1px solid #ddd;
background:#f5f5f5;
}
<div id='format'>Test 123456789</div>


2

刚遇到这个最长的线程之一,下面是我的解决方案:

parseFloat(Math.round((parseFloat(num * 100)).toFixed(2)) / 100 ).toFixed(2)

让我知道是否有人可以戳一个洞


2


2
这段代码足以满足您的要求 parseFloat(num.toFixed(2))
kva

1

您没有给我们提供全部信息。

javascript:alert(parseFloat(1).toFixed(2))当我将1.00粘贴到位置栏中时,在浏览器中显示1.00。但是,如果您随后对其进行处理,它将还原。

var num = 2
document.getElementById('spanId').innerHTML=(parseFloat(num).toFixed(2)-1)


shows 1 and not 1.00

适用于FF 50,Chrome 49和IE 8
Florian Straub


1

我必须在parseFloat()和Number()转换之间做出决定,然后才能进行toFixed()调用。这是捕获用户输入后格式化数字的示例。

HTML:

<input type="number" class="dec-number" min="0" step="0.01" />

事件处理程序:

$('.dec-number').on('change', function () {
     const value = $(this).val();
     $(this).val(value.toFixed(2));
});

上面的代码将导致TypeError异常。请注意,尽管html输入类型是“数字”,但用户输入实际上是“字符串”数据类型。但是,toFixed()函数只能在为Number的对象上调用。

我的最终代码如下所示:

$('.dec-number').on('change', function () {
     const value = Number($(this).val());
     $(this).val(value.toFixed(2));
});

我偏爱使用Number()和parseFloat()进行转换的原因是,我既不必为空的输入字符串也不必为NaN值执行额外的验证。Number()函数将自动处理一个空字符串并将其隐藏为零。


0

我真的很喜欢:

var num = 12.749;
parseFloat((Math.round(num * 100) / 100).toFixed(2)); // 123.75

将数字四舍五入为2个小数点,然后确保将其解析parseFloat() 为返回Number而不是String,除非您不在乎它是String还是Number。


我猜想如果目的是显示2个小数精度,则解析浮点数将对此造成混乱。例如parseFloat("1.00") // 1
Stijn de Witt

0

精度方法扩展数学对象

Object.defineProperty(Math, 'precision',{
   value: function (value,precision,type){
             var v = parseFloat(value),
                 p = Math.max(precision,0)||0,
                 t = type||'round';
              return (Math[t](v*Math.pow(10,p))/Math.pow(10,p)).toFixed(p);
          }
    });

console.log(
    Math.precision(3.1,3), // round 3 digits 
    Math.precision(0.12345,2,'ceil'), // ceil 2 digits
    Math.precision(1.1) // integer part
)



0

这是仅使用下限进行舍入的另一种解决方案,这意味着确保计算出的金额不会大于原始金额(有时需要交易):

Math.floor(num* 100 )/100;

0

您可以尝试以下代码:

    function FormatNumber(number, numberOfDigits = 2) {
        try {
            return new Intl.NumberFormat('en-US').format(parseFloat(number).toFixed(2));
        } catch (error) {
            return 0;
        }
    }

    var test1 = FormatNumber('1000000.4444');
    alert(test1); // 1,000,000.44

    var test2 = FormatNumber(100000000000.55555555, 4);
    alert(test2); // 100,000,000,000.56

0

试试下面的代码:

function numberWithCommas(number) { 

   var newval = parseFloat(Math.round(number * 100) / 100).toFixed(2);

   return newval.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.