Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly handle Byte values greater than 127 in Kotlin?

Imagine I have a Kotlin program with a variable b of type Byte, into which an external system writes values greater than 127. "External" means that I cannot change the type of the value it returns.

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

Both a.toByte() and b.toInt() return -128.

Imagine I want to get the correct value (128) from the variable b. How can I do it?

In other words: What implementation of magicallyExtractRightValue would make the following test run?

@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") } 

Update 1: This solution suggested by Thilo seems to work.

private fun magicallyExtractRightValue(o: Byte): Int = when {     (o.toInt() < 0) -> 255 + o.toInt() + 1     else -> o.toInt() } 
like image 946
Dmitrii Pisarenko Avatar asked Jul 29 '16 05:07

Dmitrii Pisarenko


People also ask

How do you assign a value to a byte?

If you're trying to assign hard-coded values, you can use: byte[] bytes = { (byte) 204, 29, (byte) 207, (byte) 217 }; Note the cast because Java bytes are signed - the cast here will basically force the overflow to a negative value, which is probably what you want.

What is byte in Kotlin?

Definition. A byte is an 8-bit number in Kotlin. This type is mentioned explicitly. A byte value ranges from -128 to 127. In JVM, the characteristics of this "Byte" variable is derived from the characteristics of primitive type byte of Java which has a non-nullable default value.

What are byte values?

byte: The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters.


1 Answers

With Kotlin 1.3+ you can use unsigned types. e.g. toUByte (Kotlin Playground):

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

or even require using UByte directly instead of Byte (Kotlin Playground):

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

For releases prior to Kotlin 1.3, I recommend creating an extension function to do this using and:

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

Example usage:

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") 

Example output:

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] 
like image 116
mfulton26 Avatar answered Sep 20 '22 16:09

mfulton26