38

I'm trying to write kotlin code like:

for (byte b : hash)  
     stringBuilder.append(String.format("%02x", b&0xff));

but I have nothing to do with the "&". I'm trying to use "b and 0xff" but it doesn't work. The bitwise "and" seems to work on Int, not byte.

java.lang.String.format("%02x", (b and 0xff))

it's ok to use

1 and 0xff
Cœur
  • 37,241
  • 25
  • 195
  • 267
Allen Vork
  • 1,536
  • 3
  • 16
  • 29

2 Answers2

52

Kolin provides bitwise operator-like infix functions available for Int and Long only.

So it's necessary to convert bytes to ints to perform bitwise ops:

val b : Byte = 127
val res = (b.toInt() and 0x0f).toByte() // evaluates to 15

UPDATE: Since Kotlin 1.1 these operations are available directly on Byte.

From bitwiseOperations.kt:

@SinceKotlin("1.1") 
public inline infix fun Byte.and(other: Byte): Byte = (this.toInt() and other.toInt()).toByte()
Vadzim
  • 24,954
  • 11
  • 143
  • 151
  • 7
    It's also useful to note that java does this widening conversion too. It's just implicit. – Raman Jul 14 '16 at 15:57
7

Bitwise "and" of any byte-value and 0xff will always return the original value.

It is simple to see this if you draw the bits in a diagram:

00101010   42
11111111   and 0xff
--------
00101010   gives 42
ams
  • 24,923
  • 4
  • 54
  • 75
  • 3
    No, it's used to truncate an `int` so it fits in a byte. – ams Oct 29 '15 at 12:37
  • 1
    @AllenVork bytes in java are *signed* and java converts them implicitly to an `int` when doing bitwise operations (Kotlin simply requires this to be explicit). Therefore, in order for this widening conversion to result in the expected positive int value when the initial byte value is negative, one masks the 3 higher-order bytes of the widened int value (which includes the sign bit) via the `& 0xff`. – Raman Jul 14 '16 at 14:22
  • 1
    Oh, `x & 0xff` is such a cool way to convert to int. Thanks, I'm gonna use it everywhere now. It's gonna make me look so clever! – Sarsaparilla May 05 '18 at 17:33