DoubleArray

时间:2018-02-19 23:22:37

标签: arrays floating-point kotlin double comparison

我需要比较两个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而不是==,并且行为不同。

免责声明: 在比较双重值与相等时,我意识到精确度存在风险。最终,我将尝试重构我的代码,因此它不依赖于相等,但是现在,它适用于相等测试。这不是一个关于如何比较两个双打数组的问题。

0 个答案:

没有答案