如何格式化Javascript中的float?


427

在JavaScript中,当从浮点数转换为字符串时,如何在小数点后仅获得2位数字?例如,用0.34代替0.3445434。


16
只是有些挑剔:您想除掉前两位以外的所有数字,还是要舍入到两位数字?
xtofl,2009年

Answers:


232
var result = Math.round(original*100)/100;

具体内容,以防代码不言自明。

编辑:...或toFixed按照TimBüthe的建议使用。忘了那个,谢谢(和赞扬):)


1
我在库“ Highchart”中使用了该库,该库不接受字符串值,因此toFixed对我不起作用,Math.round解决了我的问题,谢谢
Swapnil Chincholkar 2015年

4
toFixed()会模仿什么像printf()做在C.然而,toFixed()Math.round()将处理舍入不同。在这种情况下,toFixed()将具有相同的效果Math.floor()(允许您事先将原始toFixed()数字乘以10 ^ n,然后用n位数字调用)。答案的“正确性”非常取决于OP在这里想要的内容,并且两者都以自己的方式“正确”。
DDPWNAGE '18

838

有一些函数可以四舍五入。例如:

var x = 5.0364342423;
print(x.toFixed(2));

将打印5.04。

编辑: 小提琴


7
我建议不要在浏览器中使用print()
cobbal

70
注意这一点,toFixed()返回一个字符串:var x = 5.036432346; var y = x.toFixed(2) + 100; y将等于"5.03100"
Vlad

5
请注意(1e100).toFixed(2)===“ 1e + 100”
qbolec 2014年

7
另外,请注意四舍五入不一致的地方:(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
Skippy le Grand Gourou 2015年

3
如果您搜索等效的toFixed但具有一致的舍入,请使用toLocaleString:(0.345).toLocaleString('en-EN',{minimumFractionDigits:2,maximumFractionDigits:2})
fred727

185

使用时要小心 toFixed()

首先,使用数字的二进制表示形式对数字进行四舍五入可能会导致意外的行为。例如

(0.595).toFixed(2) === '0.59'

代替 '0.6'

其次,有一个IE错误toFixed()。在IE中(至少在版本7以上,没有检查IE8),以下情况成立:

(0.9).toFixed(0) === '0'

遵循kkyy的建议或使用自定义toFixed()函数可能是一个好主意,例如

function toFixed(value, precision) {
    var power = Math.pow(10, precision || 0);
    return String(Math.round(value * power) / power);
}

是的,这在创建代码以预测价格时非常重要。谢谢!+1
Fabio Milheiro

10
我建议.toFixed()在返回值中添加本机方法,这将增加所需的精度,例如:return (Math.round(value * power) / power).toFixed(precision);并且还将值作为字符串返回。否则,对于较小的小数,将忽略20的精度
William Joss Crowcroft 2011年

3
关于一个注意事项toFixed:注意,提高精度会产生意想不到的结果:(1.2).toFixed(16) === "1.2000000000000000",而(1.2).toFixed(17) === "1.19999999999999996"(在Firefox / Chrome中;在IE8中,由于IE8可以内部提供的精度较低,后者不成立)。
jakub.g

2
请注意,即使(0.598).toFixed(2)不产生0.6。它产生0.60:)
qbolec

1
此外,提防inconstistent四舍五入的:(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
Skippy le Grand Gourou 2015年

36

要注意的另一个问题是,toFixed()在数字末尾可能会产生不必要的零。例如:

var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"

这个想法是使用以下命令清理输出RegExp

function humanize(x){
  return x.toFixed(6).replace(/\.?0*$/,'');
}

RegExp尾随零(和可选小数点)匹配,以确保它看起来整数一样好。

humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"

Number.prototype.minFixed = function(decimals){返回this.toFixed(decimals).replace(/ \。?0 * $ /,“”); }
卢克·布鲁姆

这应该可以接受,结尾的零很烦人,我一直在寻找这种解决方案,gj。
exoslav

1
尾随零可能很烦人,但这恰恰是方法名称“ toFixed”承诺要做的;)
ksadowski


6

所有这些使用乘法器的解决方案都存在问题。不幸的是,kyky和Christoph的解决方案都是错误的。

请测试您的代码551.175的两位小数-它将四舍五入为551.17,而应为551.18!但是,如果您测试前。451.175可以-451.18。因此,乍一看很难发现此错误。

问题在于相乘:尝试551.175 * 100 = 55117.49999999999(ups!)

所以我的想法是在使用Math.round()之前先用toFixed()处理它;

function roundFix(number, precision)
{
    var multi = Math.pow(10, precision);
    return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}

1
这就是js中的算术问题:(551.175 * 10 * 10)!==(551.175 * 100)。对于非真实的十进制结果,必须使用十进制增量来移动逗号。
Kir Kanos 2014年

+1会引起注意,但是toFixed也会受到影响— (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)…无论使用哪种方法,最好在四舍五入之前添加一个epsilon。
Skippy le Grand Gourou 2015年

5

我想这里的关键是首先正确地取整,然后可以将其转换为String。

function roundOf(n, p) {
    const n1 = n * Math.pow(10, p + 1);
    const n2 = Math.floor(n1 / 10);
    if (n1 >= (n2 * 10 + 5)) {
        return (n2 + 1) / Math.pow(10, p);
    }
    return n2 / Math.pow(10, p);
}

// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34

现在,您可以使用toFixed(p)安全地设置此值的格式。因此,根据您的具体情况:

roundOf(0.3445434, 2).toFixed(2); // 0.34


1
function trimNumber(num, len) {
  const modulu_one = 1;
  const start_numbers_float=2;
  var int_part = Math.trunc(num);
  var float_part = String(num % modulu_one);
      float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
  return int_part+'.'+float_part;
}

一个很好的答案,除了您缺少分号(不,在es6中,分号不是过时的,在某些情况下我们仍然必须使用它们)。我只好也编辑最后一行:return float_part ? int_part+'.'+float_part : int_part;否则,如果您通过整数,它在年底返回的数字以点(例如输入:2100输出:2100.
库巴Šimonovský

0

也许您还想要十进制分隔符?这是我刚做的功能:

function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
    if (num < 0)
    {
        num = -num;
        sinal = -1;
    } else
        sinal = 1;
    var resposta = "";
    var part = "";
    if (num != Math.floor(num)) // decimal values present
    {
        part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
        while (part.length < casasDec)
            part = '0'+part;
        if (casasDec > 0)
        {
            resposta = sepDecimal+part;
            num = Math.floor(num);
        } else
            num = Math.round(num);
    } // end of decimal part
    while (num > 0) // integer part
    {
        part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
        num = Math.floor(num/1000);
        if (num > 0)
            while (part.length < 3) // 123.023.123  if sepMilhar = '.'
                part = '0'+part; // 023
        resposta = part+resposta;
        if (num > 0)
            resposta = sepMilhar+resposta;
    }
    if (sinal < 0)
        resposta = '-'+resposta;
    return resposta;
}

0

无法避免使用乘法或除法将x.xx5作为实际值的价格舍入不一致。如果您需要在客户端计算正确的价格,则应保留所有金额(以美分计)。这是由于JavaScript中数值内部表示的性质所致。请注意,Excel也存在相同的问题,因此大多数人不会注意到此现象引起的细微错误。但是,每当您添加大量计算值时,误差可能会累积,围绕此的整个理论涉及计算顺序和其他方法,以最大程度地减少最终结果中的误差。为了强调十进制值的问题,请注意,在JavaScript中0.1 + 0.2不完全等于0.3,而1 + 2等于3。


解决方案是将整个部分和小数部分分开,并以10为底的整数表示它们,而不是使用浮点数,在这里它对于prettyPrint毫无问题,但通常必须在一个底数和另一个底数之间进行选择实数和另外一个,每个都有问题
重聚

“ Excel也遇到同样的问题”。资源 ?
gaurav5430 '19

0
/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) { 
    if (!nbDec) nbDec = 100;
    var a = Math.abs(x);
    var e = Math.floor(a);
    var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
    var signStr = (x<0) ? "-" : " ";
    var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
    var eStr = e.toString();
    return signStr+eStr+"."+decStr;
}

prettyFloat(0);      //  "0.00"
prettyFloat(-1);     // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5);    //  "0.50"

0

我使用此代码来格式化浮点数。它基于,toPrecision()但是会去除不必要的零。我欢迎提出有关如何简化正则表达式的建议。

function round(x, n) {
    var exp = Math.pow(10, n);
    return Math.floor(x*exp + 0.5)/exp;
}

用法示例:

function test(x, n, d) {
    var rounded = rnd(x, d);
    var result = rounded.toPrecision(n);
    result = result.replace(/\.?0*$/, '');
    result = result.replace(/\.?0*e/, 'e');
    result = result.replace('e+', 'e');
    return result;  
}

document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');
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.