为什么 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 中的数学协处理器中实现。您可以使用简单的比例表示自然的任何对数,而无需大量计算时间。