Introduction
Converting a decimal (base-10) number to its binary (base-2) representation is one of the most fundamental programming exercises in computer science.
Although Java provides a built-in method that performs this conversion instantly, understanding the manual algorithm is extremely valuable because it teaches how different number systems work internally.
The classic conversion algorithm repeatedly:
- Divides the number by 2
- Stores the remainder
- Continues until the number becomes 0
This problem is also a popular interview question, especially with the constraint:
"Convert a decimal number to binary without using any built-in method."
In this guide, you'll learn:
- Manual decimal-to-binary conversion using a
whileloop - A recursive solution
- A
StringBuilderimplementation - Java's built-in
Integer.toBinaryString()method - How negative numbers are represented using two's complement
What Is Decimal-to-Binary Conversion?
Humans normally use the decimal number system, which has 10 digits:
0 1 2 3 4 5 6 7 8 9
Computers, however, use the binary number system, which has only two digits:
0 1
Every binary digit (bit) represents a power of 2.
For example, consider the decimal number:
13
Its binary representation is:
1101
Why?
Because:
| Binary Digit | Power of 2 | Value |
|---|---|---|
| 1 | 2³ | 8 |
| 1 | 2² | 4 |
| 0 | 2¹ | 0 |
| 1 | 2⁰ | 1 |
Adding these values:
8 + 4 + 0 + 1 = 13
So:
Decimal 13 = Binary 1101
Method 1: Using a While Loop (Manual Algorithm)
The manual conversion algorithm repeatedly divides the number by 2 and records each remainder.
These remainders form the binary digits.
Java Program
public class DecimalToBinaryLoop {
public static void main(String[] args) {
int num = 13;
String binary = "";
while (num > 0) {
int remainder = num % 2;
binary = remainder + binary;
num = num / 2;
}
System.out.println("Binary representation: " + binary);
}
}
Output
Binary representation: 1101
Step-by-Step Execution
Suppose the input is:
13
Iteration 1
Current number:
13
Divide by 2:
13 % 2 = 1
Store:
binary = "1"
Remaining number:
13 / 2 = 6
Iteration 2
Current number:
6
Remainder:
6 % 2 = 0
Update:
binary = "01"
Remaining number:
3
Iteration 3
Current number:
3
Remainder:
3 % 2 = 1
Update:
binary = "101"
Remaining number:
1
Iteration 4
Current number:
1
Remainder:
1 % 2 = 1
Update:
binary = "1101"
Remaining number:
0
The loop terminates.
Final result:
1101
Why Do We Prepend the Remainders?
Notice the statement:
binary = remainder + binary;
Instead of:
binary = binary + remainder;
Why?
Because the algorithm generates the binary digits from right to left.
For example, the remainders appear in this order:
1
0
1
1
The first remainder is actually the last binary digit.
By inserting every new remainder at the front of the string, we automatically build the correct binary representation.
Time Complexity
- Time Complexity: O(log₂ n)
- Space Complexity: O(log₂ n)
The number of iterations equals the number of binary digits required to represent the number.
Method 2: Using Recursion
The same conversion can also be implemented recursively.
Instead of storing the binary digits in a string, recursion naturally prints them in the correct order.
Java Program
public class DecimalToBinaryRecursion {
static void convert(int num) {
if (num == 0) {
return;
}
convert(num / 2);
System.out.print(num % 2);
}
public static void main(String[] args) {
int num = 13;
System.out.print("Binary representation: ");
convert(num);
System.out.println();
}
}
Output
Binary representation: 1101
How It Works
The recursive calls occur like this:
convert(13)
↓
convert(6)
↓
convert(3)
↓
convert(1)
↓
convert(0)
The base case returns immediately.
Now the recursive calls begin returning.
During the return phase:
System.out.print(num % 2);
executes in reverse order.
The printed digits become:
1
1
0
1
which forms:
1101
Why Doesn't This Need String Reversal?
The key is that the print statement comes after the recursive call.
This means:
- The recursive calls first reach the smallest value.
- Printing happens while the recursion unwinds.
- The most significant bit is printed first.
This is the same principle discussed in the "Print Numbers Without Loop" recursion example, where statements placed after the recursive call execute during the unwinding phase.
Time Complexity
- Time Complexity: O(log₂ n)
- Space Complexity: O(log₂ n)
The recursive depth equals the number of binary digits in the number.
Method 3: Using StringBuilder for Correct Digit Order
Instead of repeatedly prepending characters to a String, we can use a StringBuilder.
The idea is simple:
- Append every remainder to the end of the
StringBuilder. - Reverse the completed sequence once at the end.
This approach is generally more efficient than repeatedly creating new String objects.
Java Program
public class DecimalToBinaryStringBuilder {
public static void main(String[] args) {
int num = 13;
StringBuilder binary = new StringBuilder();
while (num > 0) {
binary.append(num % 2);
num = num / 2;
}
System.out.println("Binary representation: " + binary.reverse());
}
}
Output
Binary representation: 1101
How It Works
The remainders are generated in this order:
1
0
1
1
Instead of inserting each digit at the beginning, we simply append:
1
10
101
1011
Finally,
binary.reverse()
changes:
1011
into:
1101
which is the correct binary representation.
Why Is StringBuilder Better?
Consider this statement from Method 1:
binary = remainder + binary;
Since Java String objects are immutable, every concatenation creates a new String object.
For large strings, this becomes inefficient.
StringBuilder avoids this problem because it maintains a mutable character buffer.
Appending characters is significantly faster, and reversing once at the end is much cheaper than rebuilding a new string during every iteration.
Time Complexity
- Time Complexity: O(log₂ n)
- Space Complexity: O(log₂ n)
Method 4: Using Java's Built-In Integer.toBinaryString()
In real-world Java applications, there is usually no need to implement the conversion manually.
Java already provides a built-in method:
Integer.toBinaryString()
which performs the conversion efficiently.
Java Program
public class DecimalToBinaryBuiltIn {
public static void main(String[] args) {
int num = 13;
String binary = Integer.toBinaryString(num);
System.out.println("Binary representation: " + binary);
}
}
Output
Binary representation: 1101
Why Use the Built-In Method?
The built-in implementation:
- Is thoroughly tested.
- Is highly optimized.
- Handles edge cases correctly.
- Supports negative numbers automatically.
For production applications, this is generally the preferred solution.
The manual algorithms remain valuable for:
- Learning number system conversions
- Understanding binary representation
- Technical interviews that prohibit built-in methods
Time Complexity
- Time Complexity: O(log₂ n)
- Space Complexity: O(log₂ n)
Handling Negative Numbers (Two's Complement)
Many developers expect:
-13
to become something like:
-1101
However, Java does not represent negative integers this way.
Instead, it uses two's complement, the standard representation used by virtually all modern computers.
Java Program
public class NegativeDecimalToBinary {
public static void main(String[] args) {
int num = -13;
String binary = Integer.toBinaryString(num);
System.out.println("Binary representation of -13: " + binary);
}
}
Output
Binary representation of -13:
11111111111111111111111111110011
Why Does This Look So Different?
A Java int occupies 32 bits.
Positive numbers use those bits directly.
Negative numbers are stored using two's complement.
The process is:
- Write the positive binary representation.
- Invert every bit.
- Add 1.
This representation allows computers to perform addition and subtraction using the same hardware circuitry regardless of whether numbers are positive or negative.
Although understanding two's complement is not required for everyday Java programming, it becomes important when working with:
- Bitwise operators
- Low-level programming
- Networking
- Embedded systems
- Operating systems
How Java Handles This Internally (Memory Concept)
Methods 1 and 2
The variables:
numremainder
are primitive int values stored in the JVM stack.
However, Method 1 repeatedly creates new String objects because Java strings are immutable.
Every statement like:
binary = remainder + binary;
allocates another String object on the heap.
Method 3
StringBuilder behaves differently.
Instead of creating a new object every time, it maintains a single mutable character buffer.
Every call to:
append()
updates the existing object.
Only one reversal occurs after all digits have been collected.
This makes StringBuilder significantly more memory-efficient for repeated string operations.
Method 4
The method:
Integer.toBinaryString()
does not compute binary from scratch in the same way as the manual algorithm.
Internally, every integer is already stored in binary by the CPU.
The method simply formats those existing bits into a readable binary string.
For negative numbers, it formats the underlying 32-bit two's complement representation.
Real-Life Analogy: Making Change Using Powers of Two
Imagine you have coins worth:
1
2
4
8
16
32
...
Each coin value is a power of two.
Now suppose you want to make:
13
You choose:
8
4
1
and skip:
2
because:
8 + 4 + 1 = 13
The binary representation simply records which power-of-two coins were used:
| Coin | Used? | Binary Digit |
|---|---|---|
| 8 | Yes | 1 |
| 4 | Yes | 1 |
| 2 | No | 0 |
| 1 | Yes | 1 |
Therefore:
13 = 1101₂
The binary digits indicate exactly which powers of two contribute to the final value.
Comparison of All Methods
| Method | Readability | Handles Negative Numbers? | Time Complexity | Space Complexity | Best Used When |
|---|---|---|---|---|---|
| While Loop (String) | Easy to understand | ❌ No (requires additional handling) | O(log₂ n) | O(log₂ n) | Learning the manual conversion algorithm |
| Recursion | Elegant | ❌ No (requires additional handling) | O(log₂ n) | O(log₂ n) | Understanding recursion and digit ordering |
StringBuilder |
Clean and efficient | ❌ No (requires additional handling) | O(log₂ n) | O(log₂ n) | Manual conversion in production-quality code |
Integer.toBinaryString() |
Simplest | ✅ Yes (Two's Complement) | O(log₂ n) | O(log₂ n) | Real-world Java applications |
Note: The number of iterations (or recursive calls) is proportional to the number of binary digits, which is approximately log₂(n).
Best Practices
- Use
Integer.toBinaryString()whenever you're writing production code. It is efficient, reliable, and correctly handles both positive and negative numbers. - If you're implementing the algorithm manually, prefer
StringBuilderinstead of repeatedly concatenatingStringobjects inside a loop. - Understand why the remainders appear in reverse order. Whether you prepend each digit, reverse the final string, or use recursion, you should know how each approach produces the correct binary sequence.
- Be aware that Java represents negative integers using two's complement, not by simply adding a minus sign before the binary digits.
-
Handle the edge case where the input is
0. A manual implementation should return:0rather than an empty string.
- Compare your manual implementation against
Integer.toBinaryString()while learning to verify that your algorithm is producing correct results.
Common Mistakes Beginners Make
1. Appending Digits in the Wrong Order
Many beginners write:
binary += remainder;
This produces:
1011
instead of:
1101
because remainders are generated from the least significant bit to the most significant bit.
2. Using String Concatenation Inside a Loop
Writing:
binary = remainder + binary;
works correctly but creates a new String object during every iteration.
For repeated concatenation, StringBuilder is the preferred solution.
3. Expecting Negative Numbers to Begin with a Minus Sign
Many developers expect:
-1101
for:
-13
However,
Integer.toBinaryString(-13)
returns the 32-bit two's complement representation, not a sign-and-magnitude representation.
4. Forgetting the Edge Case for Zero
If the program uses:
while (num > 0)
then an input of:
0
causes the loop to execute zero times.
Without special handling, the output becomes an empty string instead of:
0
5. Confusing Decimal-to-Binary with Binary-to-Decimal
These are opposite algorithms.
For decimal-to-binary:
- Divide by 2.
- Record remainders.
For binary-to-decimal:
- Multiply each binary digit by its corresponding power of 2.
- Add the results.
Expert Tips for Interviews
A strong interview answer might sound like this:
"To convert a decimal number into binary without using built-in methods, I repeatedly divide the number by 2 and record each remainder. Since the remainders are generated from the least significant bit to the most significant bit, I either prepend each remainder, append them to a
StringBuilderand reverse the result, or use recursion where the print statement comes after the recursive call. In production code, I'd simply useInteger.toBinaryString(), while also noting that it represents negative numbers using two's complement rather than a leading minus sign."
Mentioning multiple approaches to solve the ordering problem and explaining two's complement demonstrates a deeper understanding than simply memorizing the algorithm.
Pros and Cons
While Loop with String
Pros
- ✅ Easy to understand
- ✅ Clearly demonstrates the division-and-remainder algorithm
- ✅ Good for beginners
Cons
- ❌ Inefficient because repeated string concatenation creates many temporary objects
Recursion
Pros
- ✅ Elegant solution
- ✅ Naturally prints binary digits in the correct order
- ✅ Demonstrates recursive thinking
Cons
- ❌ Uses recursive stack space
- ❌ Less intuitive for beginners
- ❌ Requires understanding recursive unwinding
Using StringBuilder
Pros
- ✅ Efficient
- ✅ Cleaner than repeated string concatenation
- ✅ Preferred manual implementation
Cons
- ❌ Slightly more code than the built-in solution
Using Integer.toBinaryString()
Pros
- ✅ Simplest solution
- ✅ Highly optimized
- ✅ Correctly handles negative numbers
- ✅ Production-ready
Cons
- ❌ Does not demonstrate the underlying conversion algorithm
- ❌ May not be allowed in coding interviews that prohibit built-in methods
Frequently Asked Questions
1. What is the easiest way to convert decimal to binary in Java?
Use:
Integer.toBinaryString(num)
It is the simplest and most reliable approach.
2. How do I convert decimal to binary manually?
Repeatedly:
- Divide the number by 2.
- Record the remainder.
- Continue until the quotient becomes 0.
- Reverse the order of the remainders.
3. Why do I need to reverse the remainders?
The first remainder produced is the least significant bit.
The binary number must be displayed from the most significant bit to the least significant bit, so the order must be reversed.
4. Why does recursion automatically print the digits in the correct order?
The recursive calls continue until the smallest quotient is reached.
The print statement executes during the unwinding phase, causing the most significant bits to appear first.
5. What is two's complement?
Two's complement is the standard binary representation used by computers for negative integers.
It allows arithmetic operations on positive and negative numbers to be performed using the same hardware circuitry.
6. Is StringBuilder faster than String concatenation?
Yes.
StringBuilder modifies a single mutable object, while string concatenation repeatedly creates new immutable String objects.
7. What is the time complexity of decimal-to-binary conversion?
Each iteration divides the number by 2.
Therefore:
- Time Complexity: O(log₂ n)
8. Can I use bitwise operators instead of % and /?
Yes.
These operations are equivalent:
| Arithmetic | Bitwise |
|---|---|
num % 2 |
num & 1 |
num / 2 |
num >> 1 |
Bitwise operations are commonly used in low-level programming.
9. Does Integer.toBinaryString() work for zero?
Yes.
Integer.toBinaryString(0)
returns:
0
10. Is decimal-to-binary conversion a common interview question?
Yes.
It is one of the most frequently asked number-system problems, especially with the restriction of not using built-in conversion methods.
11. How many binary digits can a Java int have?
A Java int is 32 bits wide.
Small numbers use fewer visible binary digits, while negative numbers are displayed using all 32 bits in two's complement form.
12. Can the same algorithm convert numbers to octal or hexadecimal?
Yes.
The algorithm is identical.
Simply change the divisor:
- 2 for Binary
- 8 for Octal
- 16 for Hexadecimal
For hexadecimal, remainders greater than 9 are represented using:
A B C D E F