所以我最近开始喜欢kotlin的语言.今天,在比较双打时,我遇到了不可避免的NaN分.

fun main(args: Array<String>) {
    val nan = Double.NaN
    println("1: " + (nan == nan))
    println("2: " + (nan == (nan as Number)))
    println("3: " + ((nan as Number) == nan))
}

N.B: (Double is a subtype of Number)

运行上述代码会产生:

1: false
2: true
3: true

I understand that comparing with NaN in Java returns false, so I would expect false for all expressions.

How can this behavior be explained? What is the rationale behind it?

推荐答案

这是因为(2)(3)被编译为装箱一个基元,然后进行Double.equals判断:在JVM上,基元double不能与装箱的基元进行比较.

Double.equals, in turn, checks equality by comparing doubleToLongBits(...) of the two Doubles, and for the latter there's a guarantee that

If the argument is NaN, the result is 0x7ff8000000000000L.

因此,两个NaN返回的位相等,这里忽略规则NaN != NaN.

Also, as @miensol mentioned, there's another consequence of this equality check: +0 and -0 are equal according to == check and not to equals check.

Equivalent code in Java would be:

double nan = Double.NaN;
System.out.println("1: " + (nan == nan)) //false 
System.out.println("2: " + ((Double) nan).equals(((Number) nan)))
System.out.println("3: " + ((Number) nan).equals(nan));

The last two lines call Double.equals, comparing doubleToLongBits(...).

Kotlin相关问答推荐

Android前台服务 list —Altbeacon

API迁移到Spring Boot 3后,Spring Security无法工作

我如何测试一个可组合组件没有显示,但如果它不存在也接受?

在 map 中查找键与在 kotlin 中查找 firstOrNull

Kotlin 中的 maxOf() 和 max() 方法有什么区别?

我什么时候可以在 LazyList 或 Column 的范围内使用 Composable?

Jetpack BottomNavigation - java.lang.IllegalStateException:Already attached to lifecycleOwner

为什么 Kotlin 扩展运算符在传递原始可变参数时需要 toTypedArray()?

为什么 Kotlin 需要函数引用语法?

从列表中的每个对象中 Select 属性

使用 Hilt 注入 CoroutineWorker

将 Firebase 数据快照反序列化为 Kotlin 数据类

Android Room - error: Cannot figure out how to save this field into database

Mockito 的 argThat 在 Kotlin 中返回 null

Kotlin/JS,Gradle 插件:无法加载@webpack-cli/serve命令

添加抽象的私有getter和公共setter的正确方法是什么?

使用 rxbinding 时我应该取消订阅吗?

如何根据ArrayList的对象属性值从中获取最小/最大值?

lateinit 的 isInitialized 属性在伴随对象中不起作用

如何在 Kotlin 中生成 MD5 哈希?