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;
}
}