为什么 EPSILON 用于比较两个浮点数
Why EPSILON is used in comparing two floating point numbers
我正在谷歌搜索如何查找数字 y
是否是 x
的幂并遇到了这个 link
Java
public class Solution {
public boolean isPowerOfThree(int n) {
return (Math.log10(n) / Math.log10(3)) % 1 == 0;
} }
Common pitfalls
This solution is problematic because we start using doubles, which
means we are subject to precision errors. This means, we should never
use ==
when comparing doubles. That is because the result of
Math.log10(n) / Math.log10(3)
could be 5.0000001
or 4.9999999
. This
effect can be observed by using the function Math.log()
instead of
Math.log10()
.
In order to fix that, we need to compare the result against an
epsilon
.
Java
return (Math.log(n) / Math.log(3) + epsilon) % 1 <= 2 * epsilon;
还有没看懂return (Math.log(n) / Math.log(3) + epsilon) % 1 <= 2 * epsilon;
那一行是什么意思?
为什么比较浮点数时使用EPSILON
?
正如引用部分所说,由于浮点不精确,您可以有两个应该完全相等的数字(如果创建它们的计算是按照数学精确性进行的),但它们却略有不同。
当您比较它们时,您想要考虑到这种微小的差异,并且如果它们仅相差很小(称为 epsilon),则仍然将数字视为相等。
不过,如何选择合适的 epsilon 是一个棘手的问题,并且在很大程度上取决于您的计算性质。我想由于这个原因,Java 不包含 "standard" epsilon 常量(其他一些语言包含)。
因为自然对数是用简单级数计算的。 https://en.wikipedia.org/wiki/Natural_logarithm
这样的系列可以在 CPU 中的数学协处理器中实现。您可以使用简单的比例表示自然的任何对数,而无需大量计算时间。
我正在谷歌搜索如何查找数字 y
是否是 x
的幂并遇到了这个 link
Java
public class Solution { public boolean isPowerOfThree(int n) { return (Math.log10(n) / Math.log10(3)) % 1 == 0; } }
Common pitfalls
This solution is problematic because we start using doubles, which means we are subject to precision errors. This means, we should never use
==
when comparing doubles. That is because the result ofMath.log10(n) / Math.log10(3)
could be5.0000001
or4.9999999
. This effect can be observed by using the functionMath.log()
instead ofMath.log10()
.In order to fix that, we need to compare the result against an
epsilon
.Java
return (Math.log(n) / Math.log(3) + epsilon) % 1 <= 2 * epsilon;
还有没看懂return (Math.log(n) / Math.log(3) + epsilon) % 1 <= 2 * epsilon;
那一行是什么意思?
为什么比较浮点数时使用EPSILON
?
正如引用部分所说,由于浮点不精确,您可以有两个应该完全相等的数字(如果创建它们的计算是按照数学精确性进行的),但它们却略有不同。
当您比较它们时,您想要考虑到这种微小的差异,并且如果它们仅相差很小(称为 epsilon),则仍然将数字视为相等。
不过,如何选择合适的 epsilon 是一个棘手的问题,并且在很大程度上取决于您的计算性质。我想由于这个原因,Java 不包含 "standard" epsilon 常量(其他一些语言包含)。
因为自然对数是用简单级数计算的。 https://en.wikipedia.org/wiki/Natural_logarithm 这样的系列可以在 CPU 中的数学协处理器中实现。您可以使用简单的比例表示自然的任何对数,而无需大量计算时间。