Skip navigation

Sometimes viewing the binary representation of an integer is nice.

The resulting small utility per my recent desire for such a thing is as follows:

#include <cstdint>
#include <iosfwd>
#include <limits>
#include <type_traits>

template <typename T>
class print_binary_helper
{
public:
    static_assert(std::is_integral<T>::value,
                  "Cannot print non-integer in binary.");

    template <typename U>
    friend print_binary_helper<U> print_binary(const U value);

    template <typename U>
    friend std::ostream& operator<<(std::ostream& sink,
                                    const print_binary_helper<U> source);

    template <typename U>
    friend std::wostream& operator<<(std::wostream& sink,
                                     const print_binary_helper<U> source);

private:
    explicit print_binary_helper(T value) :
    mValue(value)
    {}

    template <typename Sink, typename Char>
    Sink& do_print(Sink& sink, Char on, Char off) const
    {
        for (auto mask = T(1) << (std::numeric_limits<T>::digits - 1);
             mask != 0; mask >>= 1)
        {
            const auto isOn = (mValue & mask) != 0;
            sink << (isOn ? on : off);
        }

        return sink;
    }

    T mValue;
};

template <typename T>
std::ostream& operator<<(std::ostream& sink,
                         const print_binary_helper<T> source)
{
    return source.do_print(sink, '1', '0');
}

template <typename T>
std::wostream& operator<<(std::wostream& sink,
                          const print_binary_helper<T> source)
{
    return source.do_print(sink, L'1', L'0');
}

template <typename T>
print_binary_helper<T> print_binary(T value)
{
    return print_binary_helper<T>(value);
}

And a small example:

#include <iostream>

int main()
{
    std::cout << print_binary(0) << std::endl;
    std::cout << print_binary(111605) << std::endl;
    std::cout << print_binary(static_cast<unsigned long long>(-1) - 1) << std::endl;
}

Output:

0000000000000000000000000000000
0000000000000011011001111110101
1111111111111111111111111111111111111111111111111111111111111110

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>