1. Overview

Int is a common data type we use daily when working with Kotlin. Sometimes, we want to obtain the binary representation of integers.

In this tutorial, we’ll explore the methods available in Kotlin to achieve this task and gain a deeper understanding of the binary representation of integers.

2. Using Java’s Integer.toBinaryString() Method

When we run our Kotlin program on the JVM, all functionality offered by the Java standard library is also available for Kotlin. Therefore, we can also employ the Java approaches to obtain binary integer representations.

A handy approach is using the Integer.toBinaryString() method:

assertEquals("10110", Integer.toBinaryString(22))
assertEquals("101010", Integer.toBinaryString(42))

As we can see, we get the binary representations of 22 and 42 by passing the numbers to the method. It’s pretty straightforward.

Sometimes, we need to handle negative integers. Since we’ll revisit the representation of negative binary numbers later, let’s quickly understand how to present negative binary numbers now.

Using two’s complement is the most common technique to represent a negative binary number.  

We can follow these three steps to convert a negative decimal number to its binary representation using two’s complement:

  • Represent the absolute value of the number in binary.
  • If the original number was negative, flip all the bits (change 0s to 1s and vice versa).
  • Add 1 to the result.

Let’s take -2 as an example to demonstrate how to get its binary representation:

  • The absolute value of -2 is 2. In Java, integers are 32-bit. Therefore, 2’s binary representation is 00000000000000000000000000000010.
  • Flip all bits: 11111111111111111111111111111101
  • Add 1 to the above binary number: 11111111111111111111111111111110

If we pass -2 to the Integer.toBinaryString() method,  we get the expected result:

assertEquals("11111111111111111111111111111110", Integer.toBinaryString(-2))

Therefore, the Integer.toBinaryString() method works for negative integers, as well.

3. Using the Int.toString(radix) or UInt.toString(radix) Extension Function

Apart from using Java’s Integer.toBinaryString() method to solve the problem, in Kotlin, we can use Int.toString( radix = 2 ) to get an integer’s binary representation:

assertEquals("10110", 22.toString(radix = 2))
assertEquals("101010", 42.toString(2)) // we can omit the parameter name "radix"

However, it’s worth noting if we pass a negative integer to this function, it doesn’t represent the negative integer in binary correctly:

assertEquals("-10", (-2).toString(2))

As the test above shows, when the integer is -2, the toString(radix = 2) function returns -10 instead of the expected 11111111111111111111111111111110.

This is because Int.toString(radix = 2) is an extension function and internally calls Java’s Integer.toString(int, radix) method:

public actual inline fun Int.toString(radix: Int): String = java.lang.Integer.toString(this, checkRadix(radix))

The Integer.toString(int, radix) method supports a dynamic radix parameter. It doesn’t apply any special handling to the radix=2 case. Therefore, this method prepends the ‘‘ character to the result if the input integer is negative:

public static String toString(int i, int radix) {
    ...
    if (negative) {
        buf[--charPos] = '-';
    }
    return StringLatin1.newString(buf, charPos, (33 - charPos));
...
}

The solution is to convert the negative integer to an unsigned integer before calling Int‘s toString(radix = 2) extension:

assertEquals("11111111111111111111111111111110", (-2).toUInt().toString(2))

This method works because Int.toUInt() returns a UInt value with the same binary representation as the input Int value.

Of course, converting positive integers to UInts won’t affect the result:

assertEquals("10110", 22.toUInt().toString(radix = 2))
assertEquals("101010", 42.toUInt().toString(2))

4. Obtaining a 32-bit Binary String

We’ve mentioned that integers in Java are 32-bit. So, sometimes, we may want to get a 32-bit binary representation. To achieve that, we can first get the binary representation of the integer, then pad the binary number to a 32-bit binary format:

fun Int.to32BitBinaryString(): String = toUInt().toString(2).padStart(Int.SIZE_BITS, '0')

As the code above shows, we wrap our implementation in the extension function to32BitBinaryString(). This allows us to fluently invoke the function directly from the integer such as 42.to32BitBinaryString().

Finally, let’s test this extension function using our examples:

assertEquals("00000000000000000000000000010110", 22.to32BitBinaryString())
assertEquals("00000000000000000000000000101010", 42.to32BitBinaryString())
assertEquals("11111111111111111111111111111110", (-2).to32BitBinaryString())

5. Conclusion

In this article, we’ve explored two approaches to converting an integer to the binary representation in Kotlin:

  • Java’s Integer.toBinaryString() is also available in Kotlin.
  • Kotlin’s Int.toString(radix =2) works for positive integers. When handling negative integers, we must first convert Int to UInt and call UInt.toString(radix =2) to get the correct result.

As always, the complete source code for the examples is available over on GitHub.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.