Convert Decimal to Octal in C++

Beginner
⏱️ 9 min read
📚 Updated: May 2026
🎯 2 Code Examples
Base conversion

What you’ll learn

  • How division by eight and remainders produce octal digits 07.
  • 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 <iostream>, int main(), std::cout.
  • unsigned types 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 1718.

Decimal base 10
Octal base 8
Digits 0 – 7

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.

57

57 = 8·7 + 1, then 7 = 8·0 + 7. Remainders LSB-first: 1, 7 → octal 71.

Intuition

64 100 (oct)
Power
82
57 71 (oct)
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).

Negative values are rejected; library %o on signed types is a separate discussion.

Live result
Press “Show octal” to convert.

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

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
1

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).

c++
#include <iostream>

void decimalToOctal(unsigned int decimalNumber) {
    int octalDigits[16];
    int i = 0;
    unsigned int n = decimalNumber;

    if (n == 0u) {
        std::cout << "Octal equivalent: 0\n";
        return;
    }

    while (n != 0u) {
        octalDigits[i] = (int)(n % 8u);
        n /= 8u;
        ++i;
    }

    std::cout << "Octal equivalent: ";
    for (int j = i - 1; j >= 0; --j) {
        std::cout << octalDigits[j];
    }
    std::cout << "\n";
}

int main() {
    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.

2

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.

c++
#include <iostream>

void printOctalMsbRecursive(unsigned int n) {
    if (n >= 8u) {
        printOctalMsbRecursive(n / 8u);
    }
    std::cout << char('0' + (int)(n % 8u));
}

int main() {
    std::cout << "57 in octal: ";
    printOctalMsbRecursive(57u);
    std::cout << "\n";

    std::cout << "0 in octal: ";
    printOctalMsbRecursive(0u);
    std::cout << "\n";

    return 0;
}

Explanation

The recursion depth equals the number of octal digits; for 32-bit unsigned values that is at most 11.

std::cout << char('0' + (int)(n % 8u));

ASCII digit. Octal never needs AF 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

Octal is base 8. The remainder n % 8 is the least significant octal digit; integer division n/8 removes that digit, just like decimal to binary uses 2.
The first remainder is the rightmost (least significant) octal digit. Printing from last remainder to first yields MSB-to-LSB order.
while (n != 0) never runs, so you must print 0 explicitly; otherwise you only print the label and a blank line.
Yes: printf("%o", n) prints unsigned octal for nonnegative values (implementation-defined for negative int). It is a good library shortcut after you understand the manual algorithm.
One octal digit encodes exactly three bits. Converting binary to octal groups bits in threes from the radix point outward.
O(log8 n) = O(log n) octal digits for nonnegative n using the remainder method; the recursive print does one call per digit.

🔄 Input / output examples

Example 1 uses 57 and 0; Example 2 repeats 57 and 0 with the recursive printer.

DecimalOctal
00
77
810
5771
64100

Edge cases and pitfalls

Signed negatives with truncating division do not give a clean “unsigned octal string” without an explicit policy.

Zero

n == 0

The reference while (decimalNumber != 0) skips the loop; always print 0 explicitly.

Digits

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.

Recursion

Very wide integers

For arbitrary-precision n, prefer an iterative loop or an explicit stack to avoid deep recursion.

Prefix

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

ApproachTimeExtra space
Remainder + arrayO(log8 n) digitsO(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, divide n by 8, reverse for display.
  • Code: guard 0; use unsigned for clean nonnegative semantics.
  • Extra: octal lines up with binary in groups of three bits.
Did you know?

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.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful