Javascript 检查数字是否接近相等

Javascript 检查数字是否接近相等,javascript,Javascript,我想知道这是否可能 假设: var a = 2592; var b = 2584; if(a nearly equal to b) { // do something } 像这样 var diff = Math.abs( a - b ); if( diff > 50 ) { console.log('diff greater than 50'); } 如果绝对差值大于50,则使用Math.abs和简单的比较进行比较 var ratio = 0; if ( a > b)

我想知道这是否可能

假设:

var a = 2592;
var b = 2584;
if(a nearly equal to b) {
// do something
}
像这样

var diff = Math.abs( a - b );

if( diff > 50 ) {
    console.log('diff greater than 50');
}

如果绝对差值大于
50
,则使用
Math.abs
和简单的比较进行比较

var ratio = 0;
if ( a > b) {
   ratio = b / a;
}
else {
    ratio = a / b;
}
if (ratio > 0.90) {
    //do something
}
approxeq = function(v1, v2, epsilon) {
  if (epsilon == null) {
    epsilon = 0.001;
  }
  return Math.abs(v1 - v2) < epsilon;
};
这是真的,而

approxeq(5,5.1)
这是错误的


您可以显式地调整传入ε以满足您的需要。千分之一的内容通常涵盖我的javascript舍入问题。

一行Es6方式版本:


constapproxeq=(v1,v2,epsilon=0.001)=>Math.abs(v1-v2)浮点比较很快就会变得复杂。在很多情况下,它不像diff小于epsilon那么简单

这里有一篇关于这个主题的文章,虽然不是特定于javascript的

TLDR:

  • 当一个被比较的数字非常接近于零时,从较大的数字中减去较小的数字可能会丢失精度数字,使差值看起来比实际值小(或零)
  • 带有不同符号的非常小的数字以一种奇怪的方式工作
  • 除以零会导致问题
  • 本文中的函数(java)可以更好地解决以下情况:

    public static boolean nearlyEqual(float a, float b, float epsilon) {
        final float absA = Math.abs(a);
        final float absB = Math.abs(b);
        final float diff = Math.abs(a - b);
    
        if (a == b) { // shortcut, handles infinities
                return true;
        } else if (a == 0 || b == 0 || (absA + absB < Float.MIN_NORMAL)) {
                // a or b is zero or both are extremely close to it
                // relative error is less meaningful here
                return diff < (epsilon * Float.MIN_NORMAL);
        } else { // use relative error
                return diff / Math.min((absA + absB), Float.MAX_VALUE) < epsilon;
        }
    }
    
    public static boolean nearlyEqual(浮点a、浮点b、浮点ε){
    最终浮动absA=数学abs(a);
    最终浮动absB=数学abs(b);
    最终浮差=数学绝对值(a-b);
    如果(a==b){//,则处理无穷大
    返回true;
    }如果(a==0 | | b==0 | |(absA+absB
    在你抱怨之前:是的,那是Java,所以你必须用Javascript重写它。这只是为了说明算法,它只是从文章中复制的

    我仍然在寻找一个彻底解决这个问题的方法,最好是用一个NPM包,这样我就不必在每次需要的时候都再弄清楚这个问题

    编辑:我发现一个包实现了上面链接的文章中的解决方案(在自述文件中有相同的链接)


    与其他答案中显示的其他解决方案相比,这将是一个不太容易出错的解决方案。有几个npm包实现了简单的解决方案,这些解决方案的错误案例几乎为零,如上所述。确保在使用前查看来源。

    在什么范围内几乎相等?嘿,我知道这个公式,但chrome说ABS没有定义。!:(奇怪的是,我现在用的是chrome,它在控制台上运行得很好,你在写数学吗?也许是ABS?谢谢,只是没有用数学。有了ABS;)谢谢,这有助于我知道这个公式,但我觉得大脑放屁+1并在11分钟后接受回答。敬礼先生!较短的方法:
    ratio=Math.min(a,b)/Max.Max(b,a)
    。我希望你说,行数越短;)如果a或b为零,则会中断。此外,简单的加法/减法往往比除法便宜。对于浮点错误,除法比减法更安全。将浮点数与公认答案进行比较非常方便。=>和
    public static boolean nearlyEqual(float a, float b, float epsilon) {
        final float absA = Math.abs(a);
        final float absB = Math.abs(b);
        final float diff = Math.abs(a - b);
    
        if (a == b) { // shortcut, handles infinities
                return true;
        } else if (a == 0 || b == 0 || (absA + absB < Float.MIN_NORMAL)) {
                // a or b is zero or both are extremely close to it
                // relative error is less meaningful here
                return diff < (epsilon * Float.MIN_NORMAL);
        } else { // use relative error
                return diff / Math.min((absA + absB), Float.MAX_VALUE) < epsilon;
        }
    }