Powers of Eight
Base 8
Each digit is a coefficient on 1, 8, 64, 512…
Decimal-to-octal conversion turns a base-10 integer into a base-8 digit string (digits 0–7). This tutorial covers remainders, recursion, built-ins, a live preview, worked Python examples, edge cases, and complexity.
Base 8
Each digit is a coefficient on 1, 8, 64, 512…
n % 8
Collect digits LSD-first, then reverse for MSD-first output.
MSB first
Recurse on n // 8 before appending n % 8 — no reverse list.
Special case
Return "0" — a plain while n > 0 loop would print nothing.
3 bits each
One octal digit equals exactly three binary bits.
Complexity
About log8 n digits for nonnegative n.
Decimal-to-octal conversion writes a nonnegative integer using digits 0–7 only. Classic example: 57 = 7 × 8 + 1 → octal 71.
The classroom method divides by 8 and stacks remainders (LSD first), then reverses. Recursion or format(n, "o") can produce the same string more directly.
It generalizes the binary conversion pattern, trains base-8 place value, and links neatly to binary triplets.
First remainder is the rightmost digit.
MSD-first output needs a reverse (or recursion).
Always return "0" for input 0.
Each octal digit packs three bits.
In short: repeatedly take n % 8 and n //= 8, reverse the digits (or recurse MSD-first), and special-case zero.
Given a nonnegative integer n, return its octal representation as a string (minimal digits, no leading zeros except for 0).
# 57 → remainders 1, 7 → reverse → "71"
# 64 → "100"
# 0 → "0" | Item | Type | Description |
|---|---|---|
n | int | Nonnegative integer (define policy for negatives). |
| Return / print | str | Octal digits as a string, e.g. "71". |
function decimal_to_octal(n): // n >= 0
if n == 0:
return "0"
digits = []
while n > 0:
digits.append(n mod 8)
n = floor(n / 8)
reverse(digits)
return join(digits) | Method | Idea | Notes |
|---|---|---|
| Remainder + reverse | Collect n % 8, then reverse | Best classroom / interview explanation |
| Recursive MSD-first | Recurse on n // 8, then append n % 8 | No reverse list |
| Built-in | format(n, "o") / oct(n)[2:] | Idiomatic production Python |
| Goal | Pattern |
|---|---|
| Next digit | n % 8 |
| Drop digit | n //= 8 |
| MSD-first output | digits.reverse() or recurse first |
| Zero case | if n == 0: return "0" |
| Built-in | format(n, "o") |
| Binary grouping | 3 bits ↔ 1 octal digit |
Same octal string — different clarity and interview signaling.
% 8 + reverseShows place-value / division clearly
MSD firstCall stack delays lower digits naturally
format / octShortest production style
remainders firstExplain loops, then mention built-ins
Reach for decimal-to-octal drills when base-8 conversion and binary grouping matter.
Same remainder pattern as binary, with digits 0–7.
Octal is a compact way to read binary in groups of three.
Classic chmod modes are often written in octal.
Same idea with base 16 and digit alphabet 0–9A–F.
Fractional octal needs a different place-value story after the point.
Key benefit: one short problem that generalizes binary conversion and connects neatly to 3-bit grouping.
Nonnegative integers in JavaScript safe range, using toString(8).
Three complete Python programs — remainder + reverse, recursive MSD-first, and built-in formatting. Click View Output to reveal sample console results.
Classic divide-by-eight approach — collect, then reverse.
Collect remainder digits LSD-first, then reverse to print MSD-first.
def decimal_to_octal(n: int) -> str:
if n == 0:
return "0"
digits: list[str] = []
while n > 0:
digits.append(str(n % 8))
n //= 8
digits.reverse()
return "".join(digits)
print("Octal equivalent:", decimal_to_octal(57))
print("Octal equivalent:", decimal_to_octal(0)) Remainders come from right to left, so reversing is required for proper left-to-right octal display.
No explicit reversal list — the call stack prints higher digits first.
Recurse on n // 8, then append n % 8.
def print_octal_recursive(n: int) -> str:
if n < 8:
return str(n)
return print_octal_recursive(n // 8) + str(n % 8)
print("57 in octal:", print_octal_recursive(57))
print("0 in octal:", print_octal_recursive(0)) The call stack naturally delays lower digits until higher digits are printed — base case n < 8 returns a single digit (including 0).
Same answer with built-ins — great after you know the algorithm.
format / octMinimal digits, plus a quick binary-triplet check.
def to_octal_builtin(n: int) -> str:
if n < 0:
raise ValueError("This helper expects a nonnegative integer")
return format(n, "o")
print(to_octal_builtin(57))
print(to_octal_builtin(0))
print(oct(57)[2:]) # strip the '0o' prefix
print(format(57, "b")) # binary of 57
# 71 octal ↔ 111 001 binary (7=111, 1=001) format(n, "o") is the cleanest minimal-digit conversion. Grouping binary 111001 as 111 001 recovers octal digits 7 and 1.
If n == 0, return "0" immediately.
Append n % 8, then n //= 8 until n becomes 0.
Reverse the list (or have recursed MSD-first) and join into a string.
Return the MSD-first digit string — that is the base-8 form of n.
n = 57Trace the remainder method. Digits collect LSD-first, then reverse.
| n | n % 8 | n // 8 | digits so far |
|---|---|---|---|
57 | 1 | 7 | [1] |
7 | 7 | 0 | [1, 7] |
Reverse → 71. Check: 7 × 8 + 1 = 57.
Where decimal-to-octal conversion shows up beyond the interview prompt.
Generalizes binary conversion to another base.
Example: write decimal_to_octal(n).
Map each octal digit to three bits.
Example: 7 ↔ 111.
Unix modes are often written in octal.
Example: 755, 644.
Same remainder idea with base 16.
Example: n % 16 + digit map.
Convert to octal then back with int(s, 8).
Example: assert int(octal, 8) == n.
MSD-first print is a clean recursion demo.
Example: recurse then append remainder.
Pro Tip: say “first remainder is the LSD” before coding — same tip as for binary, with base 8.
Why this pattern works well in interviews and classwork.
Same structure as decimal-to-binary — only the divisor changes.
Three-bit groups make mental conversion fast.
format(n, "o") keeps application code short after the theory.
O(log8 n) digits are easy to argue in interviews.
Pro Tip: after binary, ask yourself “what changes for octal?” — answer: divisor 8 and digit range 0–7.
Small habits that keep decimal-to-octal solutions interview-ready.
Return "0" before the remainder loop.
Then reverse (or recurse) for MSD-first print.
Expect 71 and 10 as golden tests.
Shows you understand why octal exists historically.
Show the loop first; then format(n, "o").
Pro Tip: round-trip with int(octal, 8) to catch reverse mistakes instantly.
Mistakes that commonly break decimal-to-octal solutions.
Printing remainders in collection order reverses the digits.
→ Reverse the list (or recurse MSD-first).
while n > 0 never runs when n is 0.
→ Return "0" explicitly.
Copying a decimal digit-extraction loop is a common slip.
→ Use % 8 and // 8.
oct(n) returns 0o... which often fails string checks.
→ Use oct(n)[2:] or format(n, "o").
Very large integers can hit recursion limits.
→ Prefer the iterative remainder method for huge values.
Set rules for negative numbers early; many beginner versions accept only nonnegative input.
n == 0Without explicit handling, loop-based code can return empty output.
Either reject negatives or define representation convention clearly.
Octal never uses digits 8 or 9.
Become 10, 100, 1000 — good reverse checks.
Already octal — return unchanged as a string.
For extremely large integers, iterative methods avoid recursion depth concerns.
Handy follow-ups interviewers sometimes ask.
int(s, 8).floor(log8 n) + 1 octal digits.Try these variations to lock in the pattern.
int(s, 8)% 8 and divide by 8.Quick Takeaway: collect n % 8 remainders, reverse them (or recurse MSD-first), and special-case zero.
| Approach | Time | Extra space |
|---|---|---|
| Remainder + reverse list | O(log8 n) | O(log8 n) |
| Recursive print | O(log8 n) | O(log8 n) stack |
| Built-in format | Typically O(d) digits | O(d) output |
Here n is nonnegative and d is the number of octal digits.
Decimal-to-octal conversion is the binary remainder pattern with divisor 8: collect digits LSD-first, reverse for MSD-first output, and handle zero. Recursion and format are strong follow-ups once the theory is clear.
Practice the three examples above, then continue to Disarium numbers for a digit-power warm-up.
Always special-case 0, remember the first remainder is the LSD, and mention the 3-bit binary link.
Convert base 10 the interview-friendly way.
Remainders are digits
DefinitionDivide by 8
MathReturn "0"
Guard3 bits each
LinkO(log n)
AnalysisEach octal digit maps to exactly three binary bits. That is why octal is often taught as a quick way to compress binary.
Learn how to check whether a number equals the sum of its digits raised to their positional powers.
9 people found this page helpful