The Kotlin language has a two different way to handle integer transformations.
If I try to transform an Int
to a Short
, only the Short
bits from the Int
are taken and the value can become negative:
65535.toShort() == (-1).toShort() // 0xFFFF
However the other way is not possible, as the actual value is taken to transform the Short
to become an Int
.
-1 == (-1).toShort().toInt() // == 0xFFFF_FFFF
I’ve made some extension function to counter this behavior.
fun Byte.bitsToShort(): Short = if (this < 0) (0xFF + toInt() + 1).toShort() else toShort()
fun Byte.bitsToInt(): Int = if (this < 0) 0xFF + toInt() + 1 else toInt()
fun Byte.bitsToLong(): Long = if (this < 0) 0xFFL + toLong() + 1L else toLong()
fun Short.bitsToInt(): Int = if (this < 0) 0xFFFF + toInt() + 1 else toInt()
fun Short.bitsToLong(): Long = if (this < 0) 0xFFFFL + toLong() + 1L else toLong()
fun Int.bitsToLong(): Long = if (this < 0) 0xFFFFFFFFL + toLong() + 1L else toLong()
I know that I can use (-1).toShort().toUShort().toInt()
but its an extra step that creates a value class under the hood. I don’t know the cost of doing it this way, but it doesn’t feel right. Unsigned values are still experimental too.
Is there a better way or native way to do that with kotlin ? I’d love to see something like this be in the language itself or in the sdk.