1

I'm trying to convert a BLE native Byte handling helper to Kotlin. In the process, I noticed that in

JAVA

myByteArray[offset] += (byte)(exponent & 0xFF);

it works as expected, but when converted to kotlin KOTLIN

myByteArray[offset] += (exponent and 0x0F shl 4).toByte()

I get errors that an Integer is expected. So I assume the

"+="

is my problem and causing an integer to be assumed. So I have two questions.

1) What exactly does += do with bytes. I understand that

b += 1

is the equivelent of

b = (byte)(b + 1)

but what exactly is happening to the bytes. Is there shifting going on, or is it converting to an int, adding the values then back to a byte?

2) What is the equivelent in Kotlin and why is it failing in Kotlin. I also tried doing

  myByteArray[offset] = myByteArray[offset] + (exponent and 0x0F shl 4).toByte()

For the record, this is converting an Integer value into a 32bit Float if you are curious. Not sure if that helps at all.

The full code if you are interested for this is:

mantissa = intToSignedBits(mantissa, 12)
exponent = intToSignedBits(exponent, 4)
myByteArray[offset++] = (mantissa and 0xFF).toByte()
myByteArray[offset] = (mantissa shr 8 and 0x0F).toByte()
myByteArray[offset] += (exponent and 0x0F shl 4).toByte() //hates this line

NOTE* It says

this

because I wrote it as a ByteArray extension, so think of this as the byteArray itself.

KOTLIN version of it (ERRORS)

enter image description here

JAVA version of it (NO ERRORS):

enter image description here

I desire more than just an answer, but I'll take it lol. I would like to understand a bit more of what is going on here so I can solve this on my own in the future as well. Thanks in advance to any who take the time to explain and help.

Also while we are on the subject ;).

  private int unsignedByteToInt(byte b) {
        return b & 0xFF;
   }

why does this work in Java, but fail in Kotlin.

   private fun unsignedByteToInt(b: Byte): Int {
        return b and 0xFF
   }

Gotta be honest, I'm tired of writing Java helper classes to handle bytes, so I'm trying to figure out the idioms of Kotlin byte handling. "and" seems to only have overloads for Ints and bytes are not treated as Ints in Kotlin.

So as a bonus question, if you can explain that one, I would also appreciate it.

Sam
  • 5,342
  • 1
  • 23
  • 39

2 Answers2

1

I believe you should be using Byte#plus(Byte).

So in your case:

myByteArray[offset] = myByteArray[offset].plus((exponent and 0x0F shl 4).toByte())

.toByte() probably isn't necessary in this case, since plus() takes basically any number, but I'm not able to test it.

TheWanderer
  • 16,775
  • 6
  • 49
  • 63
  • Hi Wanderer, thanks for your response, your answer also provides me with one of the fixes I needed, unfortunately it appears someone posted it ahead of you, so I had to mark them as the answer, but I gave you an up vote. Thanks for your assistance. – Sam Sep 25 '18 at 13:22
  • They actually posted it after mine, but it's up to you. – TheWanderer Sep 25 '18 at 13:28
  • Maybe I misunderstand how StackOverflow sorts, but my understanding is the highest is the old answer on the page. You both show 15 hours ago. If I'm inaccurate and you can show me the timestamp where your answer was ahead of his, I'll gladly fix my mistake and be fair to you, otherwise I have to assume the sorting on Stack Overflow is accurate. His shows 22:09:08 – Sam Sep 25 '18 at 13:34
  • If the vote counts are the same, sorting is random on the default mode. The accepted answer, unless it is made by the asker, is always on top. If you go into the edit history for Pawel's answer, scroll down to the first revision and "Inspect Element" on the timestamp, you'll see the exact time: 22:03:39. If you do the same on my answer you'll see: 21:58:22. – TheWanderer Sep 25 '18 at 13:37
  • You can actually just mouse over the time too. – TheWanderer Sep 25 '18 at 13:43
  • yeah for some reason, it won't let me mouse over your time, it is grayed out. His was blue. I toggled the filter to oldest and his is still on top. – Sam Sep 25 '18 at 13:51
  • No, mouse over the time right over our names, not the edit history time. And make sure it's not over `answered` but over the `15 hours ago` part. – TheWanderer Sep 25 '18 at 13:52
  • interesting, my apologies. I'm not sure why it put his answer above yours. I have corrected this, and you are now the correct answer – Sam Sep 25 '18 at 13:53
1

Did You notice that breaking down your statement works?

val newBytes = (myByteArray[offset]+(exponent and 0x0F shl 4)).toByte()
myByteArray[offset] = newBytes

Main culprit of this behavior is plus operator signature. Those are all the overloads of plus for Byte:

/** Adds the other value to this value. */
public operator fun plus(other: Byte): Int
/** Adds the other value to this value. */
public operator fun plus(other: Short): Int
/** Adds the other value to this value. */
public operator fun plus(other: Int): Int
/** Adds the other value to this value. */
public operator fun plus(other: Long): Long
/** Adds the other value to this value. */
public operator fun plus(other: Float): Float
/** Adds the other value to this value. */
public operator fun plus(other: Double): Double

None of those return a Byte and there are no overloads of plusAssign, so they are implicitly created.

First it performs plus(Byte) returning Int then tries assignment, but it requires a Byte so it causes your error.

Pawel
  • 15,548
  • 3
  • 36
  • 36
  • Thanks Pawel, I ended up just converting the bytes to ints to add them and then back to Bytes, but I like this better, so I'll switch it back to this byte plus overload. Technically you provided the answer to fix my broken code so I'll mark you as the correct answer. Was hoping for more of a low level breakdown of what exactly is happening when you add the two bytes together using the + symbol, but my current assumption is that it converts to 2byte Integers, adds them then converts back to Byte object. At any rate, thanks for the help. – Sam Sep 25 '18 at 13:21
  • Sorry Pawel, turns out wanderer's answer was in before yours and was basically the same but with less detail, so I have to be fair and give him credit. Thanks again all the same. – Sam Sep 25 '18 at 13:54
  • @Sam just for the future - You are free to mark the best answer (the one that made solution most clear/in-depth, made You understand). It's not really a race - FYI I saw other answer added while I was in the middle of preparing mine, since I went ahead and took my time to look up `Byte`s source code. – Pawel Sep 25 '18 at 20:16
  • got it, point noted. I felt you both provided the same answer, so it seemed fair to give it to the first person that responded and he politely fought for it lol. Your answer supplied a bit more detail, but not enough that it blew the other one away to where it was undeniably better. hope that makes sense, my apologies for my learning of the best way to upvote here. I'll be more careful in the future and I will take your advice on this subject of choosing an answer. – Sam Sep 25 '18 at 20:51