web-dev-qa-db-fra.com

Comment gérer correctement les valeurs d'octets supérieures à 127 dans Kotlin?

Imaginez que j'ai un programme Kotlin avec une variable b de type Byte, dans laquelle un système externe écrit des valeurs supérieures à 127. "Externe" signifie que je ne peux pas changer le type de la valeur qu'il renvoie.

val a:Int = 128 val b:Byte = a.toByte()

a.toByte() et b.toInt() renvoient -128.

Imaginez que je souhaite obtenir la valeur correcte (128) De la variable b. Comment puis-je le faire?

En d'autres termes: quelle implémentation de magicallyExtractRightValue ferait exécuter le test suivant?

@Test
fun testByteConversion() {
    val a:Int = 128
    val b:Byte = a.toByte()

    System.out.println(a.toByte())
    System.out.println(b.toInt())

    val c:Int = magicallyExtractRightValue(b)

    Assertions.assertThat(c).isEqualTo(128)
}

private fun magicallyExtractRightValue(b: Byte): Int {
    throw UnsupportedOperationException("not implemented")
}

Mise à jour 1: Cette solution suggérée par Thilo semble fonctionner.

private fun magicallyExtractRightValue(o: Byte): Int = when {
    (o.toInt() < 0) -> 255 + o.toInt() + 1
    else -> o.toInt()
}
24
Dmitrii Pisarenko

Avec Kotlin 1.3+, vous pouvez utiliser types non signés . par exemple. toUByte ( Kotlin Playground ):

private fun magicallyExtractRightValue(b: Byte): Int {
    return b.toUByte().toInt()
}

ou même exiger d'utiliser UByte directement au lieu de Byte ( Kotlin Playground ):

private fun magicallyExtractRightValue(b: UByte): Int {
    return b.toInt()
}

Pour les versions antérieures à Kotlin 1.3, je recommande de créer un fonction d'extension pour ce faire en utilisant and :

fun Byte.toPositiveInt() = toInt() and 0xFF

Exemple d'utilisation:

val a: List<Int> = listOf(0, 1, 63, 127, 128, 244, 255)
println("from ints: $a")
val b: List<Byte> = a.map(Int::toByte)
println("to bytes: $b")
val c: List<Int> = b.map(Byte::toPositiveInt)
println("to positive ints: $c")

Exemple de sortie:

from ints: [0, 1, 63, 127, 128, 244, 255]
to bytes: [0, 1, 63, 127, -128, -12, -1]
to positive ints: [0, 1, 63, 127, 128, 244, 255]
37
mfulton26

Le bon vieux printf fait ce que nous voulons:

Java.lang.String.format("%02x", byte)
0
Raphael