Javascript 性能:toFixed()与数学地板(x*10000)

Javascript 性能:toFixed()与数学地板(x*10000),javascript,Javascript,我需要将两个浮点值比较到某个精度(即小数点后4位): 我看到的两个选择: Math.floor(float1 * 10000) === Math.floor(float2 * 10000); // 25 === 25 …或: float1.toFixed(4) === float2.toFixed(4) // "0.0025" === "0.0025" 因为手术每秒会发生60次,我问自己: 哪些选项具有更高的性能 其中一种选择是否更被广泛接受 还有第三种选择吗 功能楼层(一层、二层){ 返回

我需要将两个浮点值比较到某个精度(即小数点后4位):

我看到的两个选择:

Math.floor(float1 * 10000) === Math.floor(float2 * 10000); // 25 === 25
…或:

float1.toFixed(4) === float2.toFixed(4) // "0.0025" === "0.0025"
因为手术每秒会发生60次,我问自己:

  • 哪些选项具有更高的性能
  • 其中一种选择是否更被广泛接受
  • 还有第三种选择吗
  • 功能楼层(一层、二层){
    返回数学楼层(f1*10000)==数学楼层(f2*10000);
    }
    固定功能(f1、f2){
    返回f1.toFixed(4)==f2.toFixed(4);
    }
    函数减法(f1,f2){
    返回数学绝对值(f1-f2)<0.00001;
    }
    功能测试(fn){
    控制台时间(fn.名称);
    对于(设i=0;i<1000000;++i){
    fn(Math.random(),Math.random());
    }
    console.timeEnd(fn.name);
    }
    for(常数fn of[floor,toFixed,subtract]){
    试验(fn);
    }
    
    发动机基准 v8(基于Chromium的浏览器)
    • 楼层:204.911 ms
    • 固定时间:4145.529毫秒
    • 减去:292.390毫秒
    SpiderMonkey(基于Firefox的浏览器)
    • 楼层:566.81毫秒
    • 固定时间:683.56毫秒
    • 减去:423.76ms
    在您给出的两个选项中,
    Math.floor
    方法速度更快

    不过,选择
    减法可能是明智的选择

    (如果您不相信我,请自己运行此基准测试。)

    它似乎是基于round函数的toFixed,因此最好使用它来代替快速版本:

    功能快速楼层(f1、f2){
    返回~~(f1*10000)==~(f2*10000);
    
    }
    第三个选项是
    abs(float1-float2),非常感谢!为什么选择
    substract
    可能是明智的选择?因为
    subtract
    的结果在我测试过的两个引擎中的算术平均值最低,与所有其他实现相比(注意
    floor
    在基于Firefox的浏览器上不是最快的)。@kraftwer1 With floor,0.00250等于0.00259,但不等于0.00249,尽管0.00249更接近于0.00250。这就是你可能应该选择的原因(在这个答案中把fred改为“subtract”)(这个问题的另一个典型名称是“fuzzy equals”。)我也更喜欢
    subtract()
    。它基于两个数字之间的距离。备选方案将数字划分为若干类。因此,对于非常接近的数字(例如差1e-10),结果可能为假,但差1e-6变为真。
    float1.toFixed(4) === float2.toFixed(4) // "0.0025" === "0.0025"
    
    function floor(f1, f2) {
        return Math.floor(f1 * 10000) === Math.floor(f2 * 10000);
    }
    function toFixed(f1, f2) {
        return f1.toFixed(4) === f2.toFixed(4);
    }
    function subtract(f1, f2) {
        return Math.abs(f1 - f2) < 0.00001;
    }
    function test(fn) {
         console.time(fn.name);
         for (let i = 0; i < 1000000; ++i) {
             fn(Math.random(), Math.random());
         }
         console.timeEnd(fn.name);
    }
    for (const fn of [floor, toFixed, subtract]) {
        test(fn);
    }
    
    Math.round(142.89 * 100) / 100 // 142.89
    Math.floor(142.89 * 100) / 100 // 142.88