- Power
82
Convert Decimal to Octal in C
What you’ll learn
- How division by eight and remainders produce octal digits
0–7. - Why zero needs a branch and why digits are printed in reverse of collection order.
- A recursive MSB-first print without an array, a live preview, and ties to binary grouping.
Overview
Octal is base eight. To print a nonnegative decimal integer in octal, repeatedly take n % 8, then replace n by n / 8, until n is zero; emit the remainders from last to first.
Two programs
Array + reverse print (classic), then recursion for MSB-first output.
Live preview
Nonnegative safe integers via Number#toString(8).
Pair with binary
Same remainder pattern as decimal-to-binary, divisor 8 instead of 2.
Prerequisites
Integer division and modulo, arrays, for and while loops, optional recursion.
#include <stdio.h>,int main(void),printf/putchar.unsignedtypes for predictable nonnegative division (Example 1).
Decimal to octal
Each octal digit is a coefficient on a power of eight: dk8k + … + d080 with every di ∈ {0,…,7}. The peel operation n % 8 reads the least significant octal digit.
Reference value 57: 57 = 7·8 + 1, so octal digits (MSB to LSB) are 7 then 1 → 718.
Division algorithm
For n ≥ 0, let d0 = n mod 8 and n1 = ⌊n/8⌋, then repeat. The sequence of remainders read from last generated to first is the standard octal numeral for n.
5757 = 8·7 + 1, then 7 = 8·0 + 7. Remainders LSB-first: 1, 7 → octal 71.
Intuition
- Sum
7·8 + 1
Takeaway: each % 8 answers “which slice of eight fits in the current place?”
Live preview
Nonnegative integers in the JavaScript safe range. Uses Number#toString(8).
Algorithm (remainder method)
Goal: print octal digits of nonnegative n in MSB-first order.
Special case n == 0
Print 0 when n is zero; while (n != 0) alone skips the body.
Collect digits
While n > 0: push n % 8, then n /= 8.
Print reversed
Emit stored digits from last pushed to first.
📜 Pseudocode
function printOctalFromDecimal(n): // n ≥ 0
if n = 0:
output "0"; return
digits ← empty list
while n > 0:
append (n mod 8) to digits
n ← floor(n / 8)
print digits in reverse order Divide by eight with reverse print
Matches the reference flow with a zero branch and unsigned division. Uses a small digit buffer (more than enough for 32-bit magnitudes).
#include <stdio.h>
void decimalToOctal(unsigned int decimalNumber) {
int octalDigits[16];
int i = 0;
unsigned int n = decimalNumber;
if (n == 0u) {
printf("Octal equivalent: 0\n");
return;
}
while (n != 0u) {
octalDigits[i] = (int)(n % 8u);
n /= 8u;
++i;
}
printf("Octal equivalent: ");
for (int j = i - 1; j >= 0; --j) {
printf("%d", octalDigits[j]);
}
printf("\n");
}
int main(void) {
unsigned int decimalNumber = 57u;
decimalToOctal(decimalNumber);
decimalToOctal(0u);
return 0;
} Explanation
Each remainder is in 0..7 by construction, so a single decimal digit per position is enough for display (no letters until base 11).
while (n != 0u)Same stopping test as the reference, paired with an upfront 0 print.
Recursive MSB-first (no digit array)
Prints higher groups before lower ones: recurse on n/8, then emit n%8. Handles n == 0 in the base case.
#include <stdio.h>
void printOctalMsbRecursive(unsigned int n) {
if (n >= 8u) {
printOctalMsbRecursive(n / 8u);
}
putchar('0' + (int)(n % 8u));
}
int main(void) {
printf("57 in octal: ");
printOctalMsbRecursive(57u);
putchar('\n');
printf("0 in octal: ");
printOctalMsbRecursive(0u);
putchar('\n');
return 0;
} Explanation
The recursion depth equals the number of octal digits; for 32-bit unsigned values that is at most 11.
putchar('0' + (int)(n % 8u));ASCII digit. Octal never needs A–F like hexadecimal.
Optimization and library path
printf("%o", n). For unsigned int n, prints octal without loops once you accept library formatting rules.
From binary. Group bits in threes from the right to jump between bases without repeated division by eight.
Interview: state nonnegative assumption, n==0, and the 3-bit grouping trick.
❓ FAQ
🔄 Input / output examples
Example 1 uses 57 and 0; Example 2 repeats 57 and 0 with the recursive printer.
| Decimal | Octal |
|---|---|
0 | 0 |
7 | 7 |
8 | 10 |
57 | 71 |
64 | 100 |
Edge cases and pitfalls
Signed negatives with truncating division do not give a clean “unsigned octal string” without an explicit policy.
n == 0
The reference while (decimalNumber != 0) skips the loop; always print 0 explicitly.
Remainder range
For nonnegative n, n % 8 is always in 0..7. If you ever see 8 or 9, the type or sign handling is wrong.
Very wide integers
For arbitrary-precision n, prefer an iterative loop or an explicit stack to avoid deep recursion.
Leading 0 in literals
In C source, a leading 0 starts an octal literal; do not confuse string output with how you write constants.
⏱️ Time and space complexity
| Approach | Time | Extra space |
|---|---|---|
| Remainder + array | O(log8 n) digits | O(log8 n) stored digits |
| Recursion (Example 2) | O(log8 n) | O(log8 n) call frames |
printf("%o") | Implementation-defined; typically O(d) | O(1) |
Here n is the magnitude of a nonnegative input.
Summary
- Idea: collect
n % 8, dividenby8, reverse for display. - Code: guard
0; useunsignedfor clean nonnegative semantics. - Extra: octal lines up with binary in groups of three bits.
Each octal digit corresponds to a block of three binary bits, which is why Unix file modes and some literals are still written in base eight.
8 people found this page helpful
