I just stumbled upon this post on /r/kotlin: <http...
# announcements
m
I just stumbled upon this post on /r/kotlin: https://www.reddit.com/r/Kotlin/comments/axnr0o/negative_zero_00_is_equal_to_zero_sometimes/ Why does this happen? Is it a bug?
Copy code
println(-0.0 == 0.0) // true
println("${-0.0 == 0.0}") // false
Also this:
Copy code
println(-0.0 < 0.0) // false
println("${-0.0 < 0.0}") // true
s
🤔
I’m trying to figure out why this could be the case but I can’t think of any reasonable explanation
Interestingly, the following:
Copy code
println(buildString {
    append(-0.0 < +0.0)
})
produces
false
And if you run the following:
Copy code
val n = -0.0
val p = +0.0
println(“${n < p}”)
that also produces
false
c
apparently
Copy code
println(-0.0 == 0.0) // true
println("${-0.0 == 0.0}") // false
gets translated by kotlin compiler into
Copy code
boolean var0 = -0.0D == 0.0D;
System.out.println(var0);
String var1 = "false";
System.out.println(var1);
So the problem (if it is a problem) lies in the code of kotlin compiler responsible for String interpolation. Its equality algorithm is probably different from what JVM uses.
s
Looks like compiler optimization gone wrong
c
Yeah, this looks like a bug.
m
I tried with different versions of Kotlin on play.kotlinlang.org. It works as expected in v1.0.7, but not in v1.1.60 and up.
c
albeit an innocent one, if at least one of the parts in the interpolated expression is a val/var the comparison works correctly, only happens if literals are used
s
Interestingly, even when calling an inline function from string interpolation that compares the two, it still returns false. Hell of an edge case
c
that's logical, inline function gets inlined so you're back at
0.0 == -0.0
, and that gets evaluated
s
No, I mean the following
Copy code
inline fun foo() = -0.0 < 0.0

fun main() {
    println(“${foo()}”)
}
prints false
m
But that is expected. -0.0 is not less than 0.0.
s
Correct, but I would expect that it would erroneously return true, as inlining
foo
into the string interpolation would be the same as
print(“${-0.0 < 0.0}”)
n
do inline function actually count there? i recall being unable to call inline funtions in string interpolation when passing them in annotations, the compiler complained
so.. but it inline into string interpolation and do that calculation during compilation or will it just inline this and do a bunch of String building and the comparison in between ?
it compiles to
Copy code
public static final void main() {
      int $i$f$foo = false;
      String var1 = String.valueOf(-0.0D < 0.0D);
      System.out.println(var1);
   }
that explains it i think