【问题标题】:JavaScript: Round to a number of decimal places, but strip extra zerosJavaScript:四舍五入到小数位,但去掉多余的零
【发布时间】:2011-11-10 20:46:35
【问题描述】:

情况如下:我得到.9999999999999999,而我应该得到1.0
我可以承受丢失小数位的精度,所以我使用.toFixed(15),这很有效。

四舍五入有效,但问题是我得到了1.000000000000000
有没有办法四舍五入到小数位,但去掉多余的空格? p>

注意:.toPrecision 不是我想要的;我只想指定小数点后有多少个数字。
注2:我不能只使用.toPrecision(1),因为我需要对小数点后实际有数据的数字保持高精度。理想情况下,小数位数应与需要的位数一样多(最多 15 位)。

【问题讨论】:

  • 关键是 .toFixed 返回一个字符串,因此只需通过数字将其往返然后返回字符串即可重新转换它,而不会出现尾随零。
  • @Nathan:只是为了澄清。您是否只想删除使用 toFixed() 获得的 string 中的尾随零?

标签: javascript math floating-point rounding


【解决方案1】:
>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0

【讨论】:

  • 在处理负数时不要忘记将它们放在括号中:-2.34.toFixed(1) 由于运算符优先级而返回-2.3
  • 使用一元 + 运算符应该比 parseFloat 函数更快:+number.toFixed(13) 这个表达式也可以用来消除 JavaScript 数字不准确的地方,比如 1.0000000000000045。
【解决方案2】:

是的,有办法。使用parseFloat()

parseFloat((1.005).toFixed(15)) //==> 1.005
parseFloat((1.000000000).toFixed(15)) //==> 1

在此处查看实时示例:http://jsfiddle.net/nayish/7JBJw/

【讨论】:

  • 不适用于parseFloat("0.0000007"),它提供"7e-7"
【解决方案3】:

据我了解,您希望删除通过toFixed() 获得的字符串中的尾随零。这是一个纯字符串操作:

var x = 1.1230000;
var y = x.toFixed(15).replace(/0+$/, "");  // ==> 1.123

【讨论】:

  • 你是唯一真正回答这个问题的人。谢谢!
  • 这会在整数上留下点(“100.00”=>“100.”)
  • @pckill 如果您不希望将点包含在正则表达式中被替换 (...replace(/\.?0+$/, "");)。
  • 在 0 和 -0 上失败,因为 0 变成了空字符串 "",而 -0 变成了 -,这两者都不是预期的(猜测)。 @zach-snow 您建议的解决方案在 0 和 -0 上也失败了。
  • @Mugen,Gus 的回答有什么问题?
【解决方案4】:

Number(n.toFixed(15)) or +(n.toFixed(15)) 会将 15 位十进制字符串转换为数字,去除尾随零。

【讨论】:

  • 我想指出,+(n.toFixed(...)) 比 parseFloat 更有效。不知道为什么,但它也比 Chrome 中的 Number 更有效。
【解决方案5】:

如果您将返回值转换为数字,则那些尾随零将被删除。这也比parseFloat() 更简洁。

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4

这使用unary + operator,因此如果将其用作字符串操作的一部分,您需要在它之前有一个中缀+:var n=0.9999999999999999; console.log('output ' + +n.toFixed(2));。仅供参考,字符串前面的一元 + 会将其转换为数字。来自 MDN:一元 + 可以:

也可以转换整数和浮点数的字符串表示形式 作为非字符串值 true、false 和 null。两者中的整数 支持十进制和十六进制(“0x”前缀)格式。 支持负数(虽然不支持十六进制)。如果不能 解析一个特定的值,它将评估为 NaN。

【讨论】:

  • @robocat 我刚刚做了一个简单的检查; +(4.1).toFixed(4)Chrome 60 中是 4.1
  • 我不明白。这个答案被否决的原因是什么?
  • @K 你是对的,所以我删除了我之前的评论并添加到答案中(我想我在 lhs 上使用带有字符串的中缀 +,而不是正确使用一元 +。通常我会更小心!干杯)
  • 这个答案仍然适用于 NaN、Infinity、-Infinity、3e30 和 0。其他一些答案在某些极端情况下会失败。
  • (4).toFixed(2) -> Chrome 60.0.3112.113 中的“4.00”
【解决方案6】:

这些都没有真正让我得到我正在寻找的问题标题,例如,5.00 是 5,5.10 是 5.1。我的解决方案如下:

num.toFixed(places).replace(/\.?0+$/, '')

'5.00'.replace(/\.?0+$/, '') // 5
'5.10'.replace(/\.?0+$/, '') // 5.1
'5.0000001'.replace(/\.?0+$/, '') // 5.0000001
'5.0001000'.replace(/\.?0+$/, '') // 5.0001

注意:正则表达式仅在 places > 0 时有效

附: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

【讨论】:

  • 5e30 上失败(将编号更改为5e3)。角落案例是恶魔!
【解决方案7】:

有一种更好的方法可以保持精度并去除零。这需要一个输入数字,并通过一些转换的魔法将拉出任何尾随零。我发现 16 对我来说是精度限制,如果您不在冥王星上放置卫星,这非常好。

function convertToFixed(inputnum)
{

      var mynum = inputnum.toPrecision(16);
//If you have a string already ignore this first line and change mynum.toString to the inputnum

      var mynumstr = mynum.toString();
    return parseFloat(mynumstr);
    }
    alert(convertToFixed(6.6/6));

【讨论】:

    【解决方案8】:

    toFixed() method 使用定点表示法格式化 number,并返回 string

    它采用半舍入策略。

    (0.124).toFixed(2); // returns 0.12
    (0.125).toFixed(2); // returns 0.13
    

    正如您所描述的,它确实有时也会导致(可能不必要的)尾随零。

    (0.001).toFixed(2); // returns 0.00
    

    您可能不想摆脱那些尾随零,基本上您可以将其转换回number。有很多方法可以做到这一点。

    +(0.001).toFixed(2); // the shortest
    

    有关将字符串转换为数字的不同方法的概述,请查看this 问题,该问题有一些很好的答案。

    【讨论】:

      【解决方案9】:

      我发现的最有效和最下注的方法如下

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-09
        • 1970-01-01
        • 2017-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多