Fading Coder

An Old Coder’s Final Dance

Home > Tech > Content

Working with Number Bases in C++: Decimal, Octal, Hexadecimal, and Binary Conversion

Tech 1

C++ iostreams read and write integers in decimal by default. You can switch the base for formatted input and output using manipulators:

  • std::dec for decimal
  • std::oct for octal
  • std::hex for hexadecimal

There is no built-in binary manipulator for streams; printing binary typically requires a helper function or std::bitset.

Reading and Writing in Different Bases

The base you set on a stream persists until you change it again. The following example reads four integers using diffferent bases and then prints them in various bases. It also demonstrates std::showbase and std::setw.

#include <iostream>
#include <iomanip>

int main() {
    using std::cin;
    using std::cout;
    using std::endl;

    long long o{}, x1{}, x2{}, d{};

    cout << "Enter four integers in order: octal (o), hex (x1), hex (x2), decimal (d)\n";

    // Input base is set with manipulators and persists until changed
    cin >> std::oct >> o;    // read octal
    cin >> std::hex >> x1;   // read hexadecimal
    cin >> x2;               // still hexadecimal
    cin >> std::dec >> d;    // back to decimal

    // Show prefixes (0 for octal, 0x for hex) on output
    cout << std::showbase;

    cout << std::setw(12) << "o as hex:" << ' ' << std::hex << o << endl;
    cout << std::setw(12) << "x1 as dec:" << ' ' << std::dec << x1 << '\t'
         << std::setw(12) << "x2 as dec:" << ' ' << x2 << endl;
    cout << std::setw(12) << "d as oct:" << ' ' << std::oct << d << endl;

    // Restore defaults
    cout << std::dec << std::noshowbase;
    return 0;
}

Notes

  • For input, the stream base must be set on std::cin to interpret digits correctly. If the base is left as decimal, prefixes like 0 and 0x are not treated specially. If you want automatic base detection for prefixes, use std::setbase(0).
  • Base manipulators only apply to formatted extraction/insersion of integer types, not floating-point or character types.
  • The format, number, and types of inputs must match the variables you extract to, in order, or later extractions will fail.
  • Once you set a base on cin or cout, it stays in effect until you set a different one.

Printing Binary Representations

There is no standard stream manipulator for binary. Below are four common techniques to produce a binary string or print bits for unsigned integers.

#include <iostream>
#include <vector>
#include <string>
#include <bitset>
#include <limits>
#include <iomanip>

// 1) Recursive printing: most-significant bit first
void print_binary_recursive(unsigned int v) {
    if (v >= 2) {
        print_binary_recursive(v >> 1);
    }
    std::cout << (v & 1u);
}

// 2) Build a string via container (LSB to MSB, then reverse)
std::string to_binary_string(unsigned int v) {
    if (v == 0) return "0";
    std::vector<char> buf;
    while (v != 0) {
        buf.push_back(static_cast<char>('0' + (v & 1u)));
        v >>= 1;
    }
    return std::string(buf.rbegin(), buf.rend());
}

// 3) Fixed-width scan using bit operations
template <class Unsigned>
void print_binary_scan(Unsigned v) {
    static_assert(std::numeric_limits<Unsigned>::is_integer && !std::numeric_limits<Unsigned>::is_signed,
                  "Unsigned integer required");
    for (int i = std::numeric_limits<Unsigned>::digits - 1; i >= 0; --i) {
        std::cout << ((v >> i) & 1u);
    }
    std::cout << '\n';
}

// 4) Use std::bitset for a fixed-width representation
void print_binary_bitset(unsigned int v) {
    std::cout << std::bitset<sizeof(unsigned int) * 8>(v) << '\n';
}

int main() {
    unsigned int lhs = 1045;
    unsigned int rhs = 2;
    unsigned int sum = lhs + rhs;

    std::cout << std::setw(22) << "recursive(" << sum << "): ";
    print_binary_recursive(sum);
    std::cout << '\n';

    std::cout << std::setw(22) << "container(" << sum << "): "
              << to_binary_string(sum) << '\n';

    std::cout << std::setw(22) << "scan(" << sum << "): ";
    print_binary_scan(sum);

    std::cout << std::setw(22) << "bitset(" << sum << "): ";
    print_binary_bitset(sum);

    return 0;
}

Additional details

  • The recursive method prints the most-significant bit first by recursing untill the high end is reached, then unwinding to emit lower bits. Every recursive call pushes a new stack frame, which includes argumants, local variables, and a return address; deep recursion increases stack usage.
  • The container approach builds the binary representation from least-significant to most-significant bit and then reverses it for output.
  • The scan method emits a fixed number of bits (width of the type). Use an unsigned type to avoid implementation-defined shifts on signed integers.
  • std::bitset<N> offers a concise, fixed-width binary view without menual loops.

Formatting tip

  • Use std::setw(n) from to set the field width for the next output item only. For example, std::cout << std::setw(8) << value; aligns the value within an 8-character field.
Tags: C++iostream

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.