3
\$\begingroup\$

I'm trying to come up with a function to convert byte arrays to their integer representation, using both endianness, and with a signed/unsigned option.

enum class ByteOrder {
    LITTLE,
    BIG
}

fun ByteArray.toInt(byteOrder: ByteOrder = LITTLE, signed: Boolean = true): Int {
    if (isEmpty()) {
        throw UnsupportedOperationException("Cannot convert an empty byte array")
    }

    val negative = signed &&
            (this[if (byteOrder == LITTLE) size - 1 else 0]).toInt() and 0b1000000 != 0

    if (!negative) {
        return absoluteToInt(byteOrder)
    }

    // The number is stored as two's complement.
    // Thus we invert each byte and then sum 1 to obtain the absolute value
    val negatedBytes = ByteArray(size)

    for ((i, byte) in withIndex()) {
        negatedBytes[i] = byte.inv()
    }

    return -(negatedBytes.absoluteToInt(byteOrder) + 1)
}

private fun ByteArray.absoluteToInt(byteOrder: ByteOrder): Int {
    var result = 0
    var shift = 8 * (size - 1)
    val range =
        if (byteOrder == LITTLE) {
            size - 1 downTo 0
        } else {
            0 until size
        }

    for (i in range) {
        result = this[i].toInt() and 0b11111111 shl shift or result
        shift -= 8
    }

    return result
}

You can submit a byte array of arbitrary size. Example:

val bytes: ByteArray = 9388608.toBytes() // Little endian, 4 elements
val intVal: Int = bytes.toInt() // Little endian

What's your opinion? Can this be done in a better way?

\$\endgroup\$
2
  • \$\begingroup\$ Explicitly separating the logic for converting signed vs unsigned would help with readability I think \$\endgroup\$ Jul 11, 2020 at 22:11
  • \$\begingroup\$ @TedBrownlow the unsigned switch is basically signed &&, so there is no logic to separate imho. \$\endgroup\$
    – LppEdd
    Jul 11, 2020 at 22:14

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.