Binary to Octal Conversion in C, C++, Java and Python
Convert binary to octal using the group-of-3 method. C, C++, Java, and Python code with worked examples, edge-case handling, and O(n) complexity analysis.
Binary and octal share a direct conversion shortcut: one octal digit always represents exactly 3 binary bits, and the mapping is a simple lookup with no arithmetic required.
This relationship means you can convert any binary number to octal without passing through decimal. Group the binary digits into threes from the right, replace each group with its single octal digit (0 through 7), and you are done. The implementations below cover C, C++, Java, and Python using this approach, plus built-in one-liners for the cases where speed matters more than demonstrating the algorithm.
Why One Octal Digit Is Three Binary Bits
Octal is base 8. The values 0 through 7 require exactly 3 binary bits to represent, since 2^3 = 8. So the mapping is exact: every octal digit corresponds to one 3-bit group, and every 3-bit group yields one octal digit. Nothing is lost or added in translation.
The complete 3-bit to octal mapping:
| Binary group | Decimal value | Octal digit |
|---|---|---|
| 000 | 0 | 0 |
| 001 | 1 | 1 |
| 010 | 2 | 2 |
| 011 | 3 | 3 |
| 100 | 4 | 4 |
| 101 | 5 | 5 |
| 110 | 6 | 6 |
| 111 | 7 | 7 |
The same logic extends to hexadecimal (base 16). Since 2^4 = 16, one hexadecimal digit equals exactly 4 binary bits. Knowing this, you can extend the group-of-3 algorithm to hexadecimal by changing the group size to 4. The principle is identical.
Two worked examples before the code:
Binary 1111 to octal:
- Pad to a multiple of 3:
1111(4 digits) becomes001111(6 digits). - Split into groups of 3 from the left:
001and111. - Convert each group:
001= 1,111= 7. - Result: octal
17. - Verify:
1111binary = 8 + 4 + 2 + 1 = 15 decimal;17octal = 1 x 8 + 7 = 15 decimal. Match.
Binary 1101010 to octal:
- Pad to 9 digits:
001101010. - Groups:
001,101,010. - Convert:
001= 1,101= 5,010= 2. - Result: octal
152. - Verify:
1101010binary = 64 + 32 + 8 + 2 = 106 decimal;152octal = 1 x 64 + 5 x 8 + 2 = 106. Match.
Algorithm: Group-of-3 Step by Step
The algorithm takes four steps:
- Read the binary number as a string of
'0'and'1'characters. - Compute
len % 3. If it is non-zero, prepend3 - (len % 3)zeros so the total length is a multiple of 3. Binary1111(length 4,4 % 3 = 1) gets two leading zeros to become001111. - Walk the padded string from left to right in steps of 3. For each 3-character group, compute
digit[0] * 4 + digit[1] * 2 + digit[2]. This gives one octal digit in the range 0 to 7. - Concatenate all octal digits to form the result string.
Skipping the decimal intermediate is the key efficiency gain. The decimal route requires two full passes (binary to decimal, then decimal to octal) and introduces division operations. The group-of-3 approach is a single pass with only integer addition and bit-weight multiplication.
Code in C, C++, Java, and Python
The four implementations below follow the same group-of-3 algorithm. Only the string-handling idioms differ across languages.
C
#include <stdio.h>
#include <string.h>
void binaryToOctal(const char *bin) {
int len = (int)strlen(bin);
int pad = (3 - len % 3) % 3;
char padded[128] = {0};
/* Prepend zeros to reach a multiple of 3 */
for (int i = 0; i < pad; i++) padded[i] = '0';
strcpy(padded + pad, bin);
int plen = len + pad;
for (int i = 0; i < plen; i += 3) {
int val = (padded[i] - '0') * 4
+ (padded[i+1] - '0') * 2
+ (padded[i+2] - '0');
printf("%d", val);
}
printf("\n");
}
int main() {
binaryToOctal("1111"); /* 17 */
binaryToOctal("1101010"); /* 152 */
binaryToOctal("11010"); /* 32 */
return 0;
}
The expression (3 - len % 3) % 3 handles all three cases correctly: when the length is already a multiple of 3, the result is 0 (no zeros added); when the remainder is 1, two zeros are added; when the remainder is 2, one zero is added. The outer % 3 is the reason the expression does not add a full extra group of three when no padding is needed.
C++
#include <iostream>
#include <string>
using namespace std;
string binaryToOctal(string bin) {
int rem = bin.size() % 3;
if (rem)
bin = string(3 - rem, '0') + bin;
string result;
for (size_t i = 0; i < bin.size(); i += 3) {
int val = (bin[i] - '0') * 4
+ (bin[i+1] - '0') * 2
+ (bin[i+2] - '0');
result += to_string(val);
}
return result;
}
int main() {
cout << binaryToOctal("1111") << "\n"; // 17
cout << binaryToOctal("1101010") << "\n"; // 152
cout << binaryToOctal("11010") << "\n"; // 32
}
The string(3 - rem, '0') constructor creates a string of 3 - rem zero characters in one call. C++ string concatenation with + allocates a temporary for the prepended zeros; for very long binary inputs in production code, a reserve plus insert(0, ...) avoids that extra allocation.
Java
public class BinaryToOctal {
public static String convert(String bin) {
int rem = bin.length() % 3;
if (rem != 0)
bin = "00".substring(0, 3 - rem) + bin;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bin.length(); i += 3) {
int val = (bin.charAt(i) - '0') * 4
+ (bin.charAt(i+1) - '0') * 2
+ (bin.charAt(i+2) - '0');
sb.append(val);
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(convert("1111")); // 17
System.out.println(convert("1101010")); // 152
System.out.println(convert("11010")); // 32
}
}
Java strings are immutable. The expression "00".substring(0, 3 - rem) + bin builds a new string for the padded input. For a single short binary number this is fine; for a loop over thousands of inputs, a StringBuilder built from scratch avoids repeated allocation. The charAt(i) - '0' idiom converts a character '0' or '1' to integer 0 or 1 without an explicit Integer.parseInt call.
Python
def binary_to_octal(binary: str) -> str:
rem = len(binary) % 3
if rem:
binary = '0' * (3 - rem) + binary
result = ''
for i in range(0, len(binary), 3):
val = int(binary[i]) * 4 + int(binary[i+1]) * 2 + int(binary[i+2])
result += str(val)
return result
print(binary_to_octal("1111")) # 17
print(binary_to_octal("1101010")) # 152
print(binary_to_octal("11010")) # 32
Python’s int(binary[i]) converts character '0' or '1' to integer 0 or 1. The alternative ord(binary[i]) - ord('0') does the same work with an explicit ASCII subtraction, which can be marginally faster in tight loops; for placement-test inputs the difference is negligible.
Built-in Shortcuts (Python and Java)
When a placement test allows standard library functions, the conversion is one expression in both Python and Java.
Python
Python’s oct() built-in converts an integer to an octal string prefixed with 0o. Combine it with int(binary, 2) to parse the binary string as base-2 first.
def binary_to_octal_builtin(binary: str) -> str:
return oct(int(binary, 2))[2:] # [2:] strips the '0o' prefix
print(binary_to_octal_builtin("1111")) # 17
print(binary_to_octal_builtin("1101010")) # 152
The [2:] slice removes the 0o prefix. Without it, oct(int("1111", 2)) returns '0o17' rather than '17'. The int(binary, 2) call raises a ValueError if the string contains any character other than '0' or '1', which is the appropriate error for malformed input.
Java
Java’s Integer.toOctalString() takes a decimal integer and returns its octal string without a prefix. Feed it the result of Integer.parseInt(binary, 2).
public class BinaryToOctalBuiltin {
public static String convert(String binary) {
return Integer.toOctalString(Integer.parseInt(binary, 2));
}
public static void main(String[] args) {
System.out.println(convert("1111")); // 17
System.out.println(convert("1101010")); // 152
}
}
Integer.parseInt(binary, 2) throws NumberFormatException on invalid characters or on values that exceed Integer.MAX_VALUE. For binary inputs longer than 31 digits, use Long.parseLong(binary, 2) and Long.toOctalString() instead.
Complexity, Edge Cases, and Placement Context
| Aspect | Group-of-3 (manual) | Built-in (Python/Java) |
|---|---|---|
| Time complexity | O(n) — one pass through the digits | O(n) — library performs the same scan |
| Space complexity | O(n) — padded string and output string | O(n) — intermediate integer and output string |
| Works on integer input | No — string input only | Yes (via int/long parsing) |
| Handles arbitrary length | Yes, up to buffer size | Java: limited to int/long range; Python: unlimited |
Edge cases to verify before submitting in a coding round:
- Binary 0:
"0"has length 1, padding adds two zeros to give"000", which converts to octal0. Confirm the test expects"0"as output, not"00"or an empty string. - Single digit
"1": padded to"001", converts to1. Correct. - All zeros:
"000"converts to0. The loop runs once and produces the single digit 0. - Leading zeros in input:
"0001111"is valid. Padding brings it to 9 digits:"000001111", giving groups000,001,111and octal017. Some questions strip the leading octal zero; verify the expected output format.
Binary-to-octal conversion appears in placement coding rounds in two contexts. In AMCAT Automata and TCS NQT coding sections, it is a standard short problem that tests whether the student knows the 3-bit grouping rule. In technical interviews, it often extends to a follow-up: “convert binary to hexadecimal” (same idea, but 4-bit groups) or “implement the conversion without using any intermediate decimal form” (which is exactly what the group-of-3 algorithm achieves). For broader coverage of algorithm problems in these same rounds, see 20 most asked data structures interview questions with answers.
The 3-bit grouping in this problem is the same bijective pattern that appears in base64 encoding (6 binary bits per encoded character) and in tokenizer implementations for language models. TinkerLLM at ₹299 works through that connection: exercises that start from binary arithmetic problems like this one and step through how modern tokenizers partition and encode text at the bit level.
For more multi-language coding problems in the same format, see palindrome check in C, C++, Java and Python.
Primary sources
Frequently asked questions
Why does binary-to-octal conversion group bits in threes?
Octal is base 8, and 2^3 = 8. Three binary bits can represent exactly eight values (0 through 7), which are the same as the eight valid octal digits. This one-to-one mapping means one octal digit corresponds to exactly one 3-bit group, and no decimal intermediate is needed.
What does the 0o prefix mean in Python's oct() output?
The prefix '0o' signals that the digits that follow are base-8. It mirrors the '0b' prefix for binary and '0x' for hexadecimal. Strip it with [2:] to get the plain octal string without the prefix.
What happens when the binary input is 0?
The single group '000' converts to octal digit 0, giving the result '0'. In Python, oct(int('0', 2))[2:] returns '0'. Add an explicit guard in C or Java if the input string can be empty.
Which approach should I use in a placement coding test?
Use the built-in one-liner when standard library functions are allowed — it is fastest to write and least error-prone. When the question asks for a manual implementation, use the group-of-3 string approach: the algorithm is short, maps directly to the mathematical basis, and is easy to trace on paper.
What is the time complexity of binary-to-octal conversion?
O(n) in the number of binary digits. Each digit is processed once in the padding and grouping steps, and the output string is at most n/3 characters long. There is no nested iteration.
A self-paced playground for building with LLMs.
TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.
Try TinkerLLM (₹299 launch)