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
.