我需要比较两个DoubleArrays,以确定它们是否具有相同顺序的相同值。为此,我使用了contentEquals
扩展功能,但是,它将 0 和 -0 视为两个不同的值(将它们与==
进行比较对待它们是相同的。)
例如:
val x = doubleArrayOf(1.0,0.0,-0.0)
val y = doubleArrayOf(1.0,0.0, 0.0)
x[0] == y[0] // true
x[1] == y[1] // true
x[2] == y[2] // true
x contentEquals y // false
定义一个扩展函数,自己进行成对比较,
infix fun DoubleArray.reallyEqual(other:DoubleArray) = (this.size == other.size) && this.zip(other).all {it.first == it.second}
x reallyEqual y // true
产生预期结果。
我不确定这是否是一个错误,或者这是否真的是预期的结果,但是由于个别相等的测试比较真实,这是一个惊喜。
查看源代码,我们可以理解为什么会这样。 contentEquals函数委托给 java.util.Arrays :: equals
/** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public inline infix fun DoubleArray.contentEquals(other: DoubleArray): Boolean { return java.util.Arrays.equals(this, other) }
并且该方法委托Double::equals
认为这些是不同的
如果出现以下情况,则认为两个d1和d2相等:
new Double(d1).equals(new Double(d2))
(与==运算符不同,此方法认为NaN等于自身,0.0d不等于-0.0d。)
这是预期的行为,还是我期望的行为?我不确定Kotlin的错误/功能请求应该在哪里报告,这可能属于那里。如果这是预期的行为,那么代表==
而不是Double::equals
的第二种方法应该包含在标准库中。至少,文档中的注释表明此方法依赖于Double::equals
而不是==
,并且行为不同。
免责声明: 在比较双重值与相等时,我意识到精确度存在风险。最终,我将尝试重构我的代码,因此它不依赖于相等,但是现在,它适用于相等测试。这不是一个关于如何比较两个双打数组的问题。