Understanding integers types in Kotlin

hello ,
Consider this code:

fun main() {
    val LongMinimumValue: Long = -9223372036854775808 // error:the value is out of  range
    val LongMinimumValue2: Long = -9223372036854775808L // error: the value is out of range
    println("Long.MIN_VALUE: ${Long.MIN_VALUE}") // output : -9223372036854775808
}

It’s intriguing that Kotlin correctly prints -9223372036854775808 when we print Long.MIN_VALUE . But when we attempt to assign the same value directly, Kotlin throws an error, saying it’s out of range.
So, why does Kotlin treat hard-coded minimum values differently when assigning them directly versus printing Long.MIN_VALUE ?

1 Like

This is a know, strange behavior in Kotlin. I don’t know if it is considered a bug and they plan to fix it some day or it is just meant to be as it is. Is Mistake in documentation?

4 Likes

thank you

its amazing that its still a thing to this day :open_mouth:

1 Like

The problem is that -9223372036854775808L is parsed as -(9223372036854775808L), i.e. negating a positive constant, and not as a negative constant in itself.

(A clue to this is the error message, which points to the first 9 and not the leading -.)

In almost all cases, that makes no difference, of course — but for integral types, the minimum value does not have a corresponding positive value. (It’s one less, due to the way that numbers are stored in two’s complement form: a byte can hold values -128 to 127, a short -32768 to 32767, and so on.)

And you’ve hit the only case where it matters!

Once you understand the problem, there are of course many workarounds, such as:

-9223372036854775807L - 1L


9223372036854775807L + 1


Long.MIN_VALUE

(In fact, the first of those is how Kotlin defines Long.MIN_VALUE! So JetBrains are clearly aware of the issue. I guess they don’t see it as a serious problem, given that it only affects that one single Long value, and that you can always use Long.MIN_VALUE instead — which usually makes your intent clearer anyway.)

6 Likes