Kotlin Bitwise and Bitshift Operations

Bitwise and bit shift operators are used on only two integral types (Int and Long) to perform bit-level operations.

To peform these operations, Kotlin provides 7 functions using infix notation.


1. or

The or function compares corresponding bits of two values. If either of the bits is 1, it gives 1. If not, it gives 0. For example,

12 = 00001100 (In Binary)
25 = 00011001 (In Binary)

Bitwise OR Operation of 12 and 25
   00001100 or
   00011001
   ________
   00011101  = 29 (In decimal)

Example: Bitwise or Operation

fun main(args: Array<String>) {

    val number1 = 12
    val number2 = 25
    val result: Int

    result = number1 or number2   // result = number1.or(number2)
    println(result)
}

When you run the program, the output will be:

29

2. and

The and function compares corresponding bits of two values. If both bits are 1, it is evaluated to 1. If either of the bits is 0, it is evaluated to 0. For example,

12 = 00001100 (In Binary)
25 = 00011001 (In Binary)

Bit Operation of 12 and 25
   00001100 and
   00011001
   ________
   00001000  = 8 (In decimal)

Example: Bitwise and Operation

fun main(args: Array<String>) {

    val number1 = 12
    val number2 = 25
    val result: Int

    result = number1 and number2   // result = number1.and(number2)
    println(result)
}

When you run the program, the output will be:

8

3. xor

The xor function compares corresponding bits of two values. If corresponding bits are different, it gives 1. If corresponding bits are same, it gives 0. For example,

12 = 00001100 (In Binary)
25 = 00011001 (In Binary)

Bitwise OR Operation of 12 and 25
   00001100 xor
   00011001
   ________
   00010101  = 21 (In decimal)

Example: Bitwise xor Operation

fun main(args: Array<String>) {

    val number1 = 12
    val number2 = 25
    val result: Int

    result = number1 xor number2   // result = number1.xor(number2)
    println(result)
}

When you run the program, the output will be:

21

4. inv()

The inv() function inverts the bit pattern. It makes every 0 to 1, and every 1 to 0.

35 = 00100011 (In Binary)

Bitwise complement Operation of 35
  00100011 
  ________
  11011100  = 220 (In decimal)

Example: Bitwise complement

fun main(args: Array<String>) {

    val number = 35
    val result: Int

    result = number.inv()
    println(result)
}

When you run the program, the output will be:

-36

Why are we getting output -36 instead of 220?

It's because the compiler is showing 2's complement of that number; negative notation of the binary number. 

For any integer n, 2's complement of n will be -(n+1).

 Decimal         Binary                      2's complement
---------       ---------          ---------------------------------------  
0             00000000          -(11111111+1) = -00000000 = -0(decimal)
1             00000001          -(11111110+1) = -11111111 = -256(decimal)
12            00001100          -(11110011+1) = -11110100 = -244(decimal)
220           11011100          -(00100011+1) = -00100100 = -36(decimal)

Note: Overflow is ignored while computing 2's complement.

The bitwise complement of 35 is 220 (in decimal). The 2's complement of 220 is -36. Hence, the output is -36 instead of 220.


5. shl

The shl function shifts bit pattern to the left by certain number of specified bits, and zero bits are shifted into the low-order positions.

212 (In binary: 11010100)

212 shl 1 evaluates to 424 (In binary: 110101000)
212 shl 0 evaluates to 212 (In binary: 11010100)
212 shl 4 evaluates to 3392 (In binary: 110101000000)

Example: Bitwise left shift

fun main(args: Array<String>) {
    val number = 212

    println(number shl 1)
    println(number shl 0)
    println(number shl 4)
}

When you run the program, the output will be:

424
212
3392

6. shr

The shr function shifts bit pattery to the right by certin number of specified bits.

212 (In binary: 11010100)

212 shr 1 evaluates to 106 (In binary: 01101010)
212 shr 0 evaluates to 212 (In binary: 11010100)
212 shr 8 evaluates to 0 (In binary: 00000000)

If the number is a 2's complement signed number, the sign bit is shifted into the high-order positions.

fun main(args: Array<String>) {
    val number = 212

    println(number shr 1)
    println(number shr 0)
    println(number shr 8)
}

When you run the program, the ouput will be:

106
212
0

7. ushr

The ushr function shifts zero into the leftmost position.


Example: signed and unsigned Right Shift

fun main(args: Array<String>) {
    val number1 = 5
    val number2 = -5

    // Signed right shift
    println(number1 shr 1)

    // Unsigned right shift
    println(number1 ushr 1)

    // Signed right shift
    println(number2 shr 1)

    // Unsigned right shift
    println(number2 ushr 1)
}

When you run the program, the output will be:

2
2
-3
2147483645

Notice, how signed and unsigned right shift function works differently for 2's complement.

The 2's complement of 2147483645 is 3.

Did you find this article helpful?