JavaScript:修剪.toPrecision()尾随零

时间:2013-05-09 21:27:16

标签: javascript math precision

我正在使用JavaScript创建在线计算器。

我有这个来计算:

eval(expression).toPrecision(10);

几乎在所有情况下都会产生正确的输出。 E.g。

eval('456456+45646486*45646884').toPrecision(10)
// Output: "2.083619852e+15"

eval('1/0').toPrecision(10)
// Output: "Infinity"

然而

eval('4*1').toPrecision(10)
// Output: "4.000000000"

如何修剪尾随零还保留上面的好输出?

3 个答案:

答案 0 :(得分:9)

使用toPrecision后除以1。 Javascript将跟踪零,并且不需要正则表达式。

答案 1 :(得分:2)

只有全零小数

  eval('4*1').toPrecision(10).replace(/\.0+$/,"")

零结束小数:

  eval('4.5*1').toPrecision(10).replace(/\.([^0]+)0+$/,".$1")

编辑:处理所有零和结束零情况

编辑:如果你总是首先使用.toPrecision(),因此总是有一个“。”,你可以删除任何尾随的零:

  eval('4.5*1').toPrecision(10).replace(/0+$/,"")

编辑:处理尾随小数:

eval('4.5*0').toPrecision(10).replace(/\.?0+$/,"")

答案 2 :(得分:1)

以下replace()调用将替换所有尾随0和尾随.(如果存在):

eval(expression).toPrecision(10).replace(/(?:\.0+|(\.\d+?)0+)$/, "$1")

它是如何工作的?

/(?:\.0+|(\.\d+?)0+)$/在字符串末尾($)查找\.0+(\.\d+?)0+?:阻止\.0+|(\.\d+?)0+成为"captured"

\.0+将匹配.,后跟任意数量的0

(\.\d+?)0+将匹配.,后跟至少一位数字,后跟至少一位0?确保0+尽可能多地与0匹配。括号“捕获”非0 s。

replace()上的第二个参数是替换匹配内容的新字符串。 $1是各种变量,并告诉replace()将匹配的值替换为第一个捕获的值(因为1位于$之后)。在这种情况下,第一个捕获的值是\.\d+?匹配的任何值。

所以,最后:

  1. .后跟任意数量的0将被丢弃
  2. .后跟非0 s后跟0 s会丢弃0
  3. 实施例

    为了比较123 .40*14*140*1的精确度方法,请参见下文。每组中的第一个(粗体)项是此方法。红色项目是与预期不符的项目。

    var tests = [
      '.04*1',
      '.40*1',
      '4*1',
      '40*1'
    ];
    var results = {};
    for (var i = 0; i < tests.length; i += 1) {
      results[i] = {};
      for (var p = 1; p < 3; p += 1) {
        results[i][p] = {};
        results[i][p][0] = {
          'output': eval(tests[i]).toPrecision(p).replace(/(?:\.0+|(\.\d+?)0+)$/, "$1"),
          'regex': '/(?:\.0+|(\.\d+?)0+)$/, "$1"'
        };
        results[i][p][1] = {
          'output': eval(tests[i]).toPrecision(p).replace(/\.0+$/, ""),
          'regex': '/\.0+$/, ""'
        };
        results[i][p][2] = {
          'output': eval(tests[i]).toPrecision(p).replace(/\.([^0]+)0+$/, ".$1"),
          'regex': '/\.([^0]+)0+$/, ".$1"'
        };
        results[i][p][3] = {
          'output': eval(tests[i]).toPrecision(p).replace(/0+$/, ""),
          'regex': '/0+$/, ""'
        };
        results[i][p][4] = {
          'output': eval(tests[i]).toPrecision(p).replace(/\.?0+$/, ""),
          'regex': '/\.?0+$/, ""'
        };
      }
    }
    for (var i in results) {
      $("#result").append("<h1>" + tests[i] + "</h1>");
      for (var p in results[i]) {
        var expected = null;
        for (var t in results[i][p]) {
          var div = $("<div></div>");
          if (t == 0) {
            expected = results[i][p][t].output;
            div.addClass("expected");
          } else if (results[i][p][t].output !== expected) {
            div.addClass("invalid");
          }
          div.append("P" + p + ": " + results[i][p][t].output);
          div.append(" <small>" + results[i][p][t].regex + "</small>");
          $("#result").append(div);
        }
        $("#result").append("<br>");
      }
    }
    body { font-family: monospace; }
    .expected { font-weight: bold; }
    .invalid { color: red; }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <div id="result"></div>