保留两位小数,比想象中的要难
发布于 5 年前 作者 zengming00 8943 次浏览 来自 问答

都知道乘100取整然后再除100,但是 console.log(Math.floor(5.1 * 100) / 100) 输出的并不是5.1而是5.09

想转成字符串,然后截字符串的方式来做,然而 console.log((0.0000001).toString()) 输出 1e-7

想用 toFixed(3) 保留三位,然后再去掉一位,然而 console.log((5.159999999999).toFixed(5)) // 5.16000

最终想到一个方法,似乎能够实现不四舍五入的保留两位小数,目前这些能测试通过,但是没有进行更严格的测试 const fixed2 = (v) => (((v * 1000) | 0) / 10 | 0) / 100;

一个保留两位小数的功能竟然比我想象的难多了

11 回复

发技术贴,支持

说了这么多你是什么场景。

var num =2.446242342;
num = num.toFixed(2);  // 输出结果为 2.45
Math.floor(15.7784514000 * 100) / 100   // 输出结果为 15.77
Number(15.7784514000.toString().match(/^\d+(?:\.\d{0,2})?/))   // 输出结果为 15.77,不能用于整数如 10 必须写为10.0000

不知道你是什么场景。 我遇到过的需要舍掉小数的情况 1.给用户显示用的,只显示小数点后五位(记得外汇期货一般是这样)或者七位就差不多了,一般是给足够精度,然后客户端处理显示。 2.帧同步的服务器需要定点数,一般都有现成的定点数的库,或者参考一下unity或者unreal现成的实现一下。

可以考虑用下库 https://github.com/MikeMcl/decimal.js/

第一次知道 js 运算不精确的时候我是崩溃的,还好找到一个库可以弥补

浮点存储引起的精度问题,可以用toPrecision:

5.192.toPrecision(3)

@zuohuadong 你的方法用楼主给出的值试试?有很多边界情况的

// 将数字转换为字符串并保留指定小数位
// 未验证参数, 参数必须为数字
fixed = function (num, len = 2) { 
    num = String(num)
    len = parseInt(len)
    const pad = new Array(len + 1).join('0')

    if (num.indexOf('e-') > 0) {
        num = '0' + String(Number(num) + 1).substr(1)
    }

    const arr = num.split('.')
    if (len < 1) {
        return arr[0]
    }
    arr[1] = (arr.length < 2 ? pad : arr[1] + pad).substr(0, len)
    return arr.join('.')
}

这样可以吗

Math.round(5.1 * 100) / 100

推荐两个专门处理JS浮点数问题的插件:

1、https://github.com/nefe/number-precision 2、https://github.com/josdejong/mathjs

希望能帮到你

可以总是通过加上一个很小的数,就能得到正确的 integer: console.log(Math.floor(5.1 * 100 + 10e-7) / 100)

回到顶部