https://kotlinlang.org logo
Title
s

Stefan Oltmann

05/10/2022, 10:32 AM
Bitshifting for bytes is not supported in Kotlin and I try to figure out how I can translate this method into Kotlin code:
/**
 * Returns an unsigned 16-bit int calculated from the next two bytes of the sequence.
 *
 * @return the 16 bit int value, between 0x0000 and 0xFFFF
 */
public int getUInt16() {
        return (getByte() << 8 & 0xFF00) |
               (getByte()      & 0xFF);
}
If I add
.toInt()
I can use the
shl
function, but the result is wrong. Is there already a standard function for this calculation?
1
k

Klitos Kyriacou

05/10/2022, 11:15 AM
Why doesn't
(getByte().toInt() shl 8 and 0xFF00) or (getByte().toInt() and 0xFF)
work for you?
m

msoulatre

05/10/2022, 11:16 AM
I don't know why you get wrong results, this is how I do it, and it seems to work as expected :
fun ByteArray.readShort(offset: Int = 0): Int {
    return (((this[offset+0].toInt() and 0xff) shl 8) or
            ((this[offset+1].toInt() and 0xff)))
}
I do wonder if there is a better way with standard functions.
k

Klitos Kyriacou

05/10/2022, 11:18 AM
What is your
getByte()
doing? Is it, for example, reading from a ByteBuffer? If so, there's already a
getShort()
that does what you want.
p

phldavies

05/10/2022, 11:19 AM
If you’re using a
ByteBuffer
instance (assumedly from the
getByte()
calls) then you can do
getShort().toUShort()
to get a
UShort
, or
getShort().toInt() and 0xFFFF
(or
getShort().toUShort().toInt()
) to get it as an
Int
If you weren’t aware, Kotlin does have unsigned integer types
s

Stefan Oltmann

05/10/2022, 11:42 AM
Thank you all a lot.
Why doesn't
(getByte().toInt() shl 8 and 0xFF00) or (getByte().toInt() and 0xFF)
work for you?
That works, thank you. I used IDEA automatic Java to Kotlin conversion and overlooked a missing paranthesis. 🙈 I expected the problem somewhere else. 🙄 This is correct:
fun getUInt16(firstByte: Byte, secondByte: Byte): Int =
    firstByte.toInt() shl 8 and 0xFF00 or (secondByte.toInt() and 0xFF)
And this returns the wrong result:
fun getUInt16(firstByte: Byte, secondByte: Byte): Int =
    firstByte.toInt() shl 8 and 0xFF00 or secondByte.toInt() and 0xFF
😅 2
c

Chris Miller

05/10/2022, 2:28 PM
I filed a similar bug on this a while ago, it caused me quite a bit of head-scratching and debugging at the time: https://youtrack.jetbrains.com/issue/KTIJ-19959/Java-to-Kotlin-coversion-fails-to-take-into-account-operator-pre
:thank-you: 1
❤️ 2
s

Stefan Oltmann

05/10/2022, 2:32 PM
Exactly that happened to me. Thank you for reporting. 🙂