【问题标题】:How to format a float as integer when .toFixed(2) gives zeros after the decimal point?当 .toFixed(2) 小数点后为零时,如何将浮点数格式化为整数?
【发布时间】:2018-06-20 12:54:48
【问题描述】:

我想知道实现以下目标的最短和最安全的方法是什么:

假设我有一个值为1.200123 的浮点变量。在我们的可视化中,我想用两位小数显示这个值,所以我现在使用myFloat.toFixed(2);,它给了我1.20

没关系。但是,如果结果输出的小数位只有零怎么办?例如值1.000043 变成1.00

对于上述情况:如何省略小数点和零而只得到1 作为输出,最好不解析和操作来自.toFixed(2) 的字符串?

【问题讨论】:

    标签: javascript numbers number-formatting


    【解决方案1】:

    ...最好不解析和操作来自 .toFixed(2) 的字符串?

    好吧,你可以用数字来做,虽然我担心在数字逻辑和 toFixed's logic 之间得到完美匹配,因为 toFixed 的定义包括如下短语:

    n 为整数,其精确数学值 n ÷ 10f - x 尽可能接近于零。如果有两个这样的 n,则选择较大的 n

    所以我可能只是更新字符串,这不是很多工作:

    function formatNumber(num) {
        return num.toFixed(2).replace(/\.00$/, "");
    }
    
    function test(num) {
        console.log(num, "=>", formatNumber(num));
    }
    test(1.01);
    test(1.43);
    test(23.7);
    test(1.200123);
    test(1.000043);
    test(1.007);
    test(1.0007);

    但这里有一个近似的数值方法,它至少与上面测试用例的结果相匹配:

    function formatNumber(num) {
        var check = Math.round(num * 100) / 100;
        var rounded = Math.round(check);
        if (rounded == check) {
            return String(rounded);
        }
        return num.toFixed(2);
    }
    
    function formatNumberViaToFixed(num) {
        return num.toFixed(2).replace(/\.00$/, "");
    }
    
    function test(num) {
        var formatted = formatNumber(num);
        var viaToFixed = formatNumberViaToFixed(num);
        if (formatted == viaToFixed) {
            console.log(num, "=>", formatted);
        } else {
            console.log(num, "=>", formatted, "ERROR: Should be", viaToFixed);
        }
    }
    test(1.01);
    test(1.43);
    test(23.7);
    test(1.200123);
    test(1.000043);
    test(1.007);
    test(1.0007);
    .as-console-wrapper {
      max-height: 100% !important;
    }

    【讨论】:

    • 谢谢,T.J.!当有“。”以外的其他字符时,这是“区域设置安全”吗?作为小数点?这就是我在尝试避免使用字符串时一直在考虑的问题。
    • @Robert - 是的,toFixed 不支持区域设置:tc39.github.io/ecma262/#sec-number.prototype.tofixed 但是,如果是,您可以改用 .replace(/\D00/, ""),因为存在任何非数字成为小数点。 :-)
    • @wiesion - 我做了,虽然肯定不彻底,沿着这些思路:jsfiddle.net/zn0ytkpc 出了什么问题?我完全同意修复或删除。 (虽然盲目 C&P 的人得到了他们应得的。:-))提前谢谢。
    • OP 要求 1.200123 => 1.201.000043 => 1 - 这是关于通过忽略某个数字后的浮点值来创建一个 int - 你的正则表达式会这样做,但数学方法没有(它为1.000043 提供1.00
    • 确实如此,所以让我们结束这个问题 - 这是一个很好的建设性会议:)
    【解决方案2】:

    你可以使用Number(myFloat.toFixed(2))

    虽然这会生成一个类型为 number 而不是 string 的值,但您可以在字符串表达式中使用它(隐式调用其 .toString() 方法),或显式调用 .toString(),以生成您想要的字符串格式想要。

    由于Number.toString() 没有特殊格式,将字符串转换为数字然后返回会从.toFixed() 生成的舍入值中删除尾随零。

    这种方法的缺点是它将1.10 转换为"1.1" 而不是"1.10",这可能是也可能不是您想要的可视化。

    【讨论】:

    • 我还没有想到,有趣的方法!
    【解决方案3】:

    我会在Number 原型中创建这个有条件的toFixed 方法,最终将调用this.toFixed 方法,这样您就可以保持原来的行为并且只调整传递给它的数字数量——即可以使用Math.powMath.trunc 轻松完成。

    Object.defineProperty(Number.prototype, 'toConditionalFixed', {
      enumerable: false,
      writable: false,
      configurable: false,
      value: function(digits) {
        let comp = Math.pow(10, digits);
        return this.toFixed(Math.trunc(this * comp) % comp === 0 ? 0 : digits);
      }
    });
    
    
    console.log(
      (1.200123).toConditionalFixed(2),
      '|',
      (1.200123).toConditionalFixed(3),
      '|',
      (1.200123).toConditionalFixed(4),
      '|',
      (1.000043).toConditionalFixed(2),
      '|',
      (1.000043).toConditionalFixed(3),
      '|',
      (1.000043).toConditionalFixed(4),
      '|',
      (1.000043).toConditionalFixed(5)
    );

    编辑

    为了完整起见,Number.prototype 中的相同方法适用于 RegExp:

    Object.defineProperty(Number.prototype, 'toConditionalFixed', {
      enumerable: false,
      writable: false,
      configurable: false,
      value: function(digits) {
        let re = new RegExp("\\." + "0".repeat(digits)  + "$");
        return this.toFixed(digits).replace(re, "");
      }
    });
    
    console.log(
      (1.200123).toConditionalFixed(2),
      '|',
      (1.200123).toConditionalFixed(3),
      '|',
      (1.200123).toConditionalFixed(4),
      '|',
      (1.000043).toConditionalFixed(2),
      '|',
      (1.000043).toConditionalFixed(3),
      '|',
      (1.000043).toConditionalFixed(4),
      '|',
      (1.000043).toConditionalFixed(5)
    );

    【讨论】:

      猜你喜欢
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      • 2011-09-08
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多