neuromancer
neuromancer

Reputation: 55469

How to convert an int to a binary string representation in C++

I have an int that I want to store as a binary string representation. How can this be done?

Upvotes: 17

Views: 60092

Answers (10)

DVK
DVK

Reputation: 129363

http://www.phanderson.com/printer/bin_disp.html is a good example.

The basic principle of a simple approach:

  • Loop until the # is 0
  • & (bitwise and) the # with 1. Print the result (1 or 0) to the end of string buffer.
  • Shift the # by 1 bit using >>=.
  • Repeat loop
  • Print reversed string buffer

To avoid reversing the string or needing to limit yourself to #s fitting the buffer string length, you can:

  • Compute ceiling(log2(N)) - say L
  • Compute mask = 2^L
  • Loop until mask == 0:
  • & (bitwise and) the mask with the #. Print the result (1 or 0).
  • number &= (mask-1)
  • mask >>= 1 (divide by 2)

Upvotes: 2

antonyjr
antonyjr

Reputation: 61

This is my best implementation of converting integers(any type) to a std::string. You can remove the template if you are only going to use it for a single integer type. To the best of my knowledge , I think there is a good balance between safety of C++ and cryptic nature of C. Make sure to include the needed headers.

template<typename T>
std::string bstring(T n){
    std::string s;
    for(int m = sizeof(n) * 8;m--;){
            s.push_back('0'+((n >> m) & 1));
    }
    return s;
}

Use it like so,

std::cout << bstring<size_t>(371) << '\n';

This is the output in my computer(it differs on every computer),

0000000000000000000000000000000000000000000000000000000101110011

Note that the entire binary string is copied and thus the padded zeros which helps to represent the bit size. So the length of the string is the size of size_t in bits.

Lets try a signed integer(negative number),

std::cout << bstring<signed int>(-1) << '\n';

This is the output in my computer(as stated , it differs on every computer),

11111111111111111111111111111111

Note that now the string is smaller , this proves that signed int consumes less space than size_t. As you can see my computer uses the 2's complement method to represent signed integers (negative numbers). You can now see why unsigned short(-1) > signed int(1)

Here is a version made just for signed integers to make this function without templates , i.e use this if you only intend to convert signed integers to string.

std::string bstring(int n){
    std::string s;
    for(int m = sizeof(n) * 8;m--;){
            s.push_back('0'+((n >> m) & 1));
    }
    return s;
}

Upvotes: 0

risingballs
risingballs

Reputation: 195

Solution without reverse, no additional copy, and with 0-padding:

#include <iostream>
#include <string>

template <short WIDTH>
std::string binary( unsigned x )
{
    std::string buffer( WIDTH, '0' );
    char *p = &buffer[ WIDTH ];

    do {
        --p;
        if (x & 1) *p = '1';
    }
    while (x >>= 1);

    return buffer;
}

int main()
{
    std::cout << "'" << binary<32>(0xf0f0f0f0) << "'" << std::endl;
    return 0;
}

Upvotes: 0

fredoverflow
fredoverflow

Reputation: 263078

I have an int that I want to first convert to a binary number.

What exactly does that mean? There is no type "binary number". Well, an int is already represented in binary form internally unless you're using a very strange computer, but that's an implementation detail -- conceptually, it is just an integral number.

Each time you print a number to the screen, it must be converted to a string of characters. It just so happens that most I/O systems chose a decimal representation for this process so that humans have an easier time. But there is nothing inherently decimal about int.

Anyway, to generate a base b representation of an integral number x, simply follow this algorithm:

  1. initialize s with the empty string

  2. m = x % b

  3. x = x / b

  4. Convert m into a digit, d.

  5. Append d on s.

  6. If x is not zero, goto step 2.

  7. Reverse s

Step 4 is easy if b <= 10 and your computer uses a character encoding where the digits 0-9 are contiguous, because then it's simply d = '0' + m. Otherwise, you need a lookup table.

Steps 5 and 7 can be simplified to append d on the left of s if you know ahead of time how much space you will need and start from the right end in the string.

In the case of b == 2 (e.g. binary representation), step 2 can be simplified to m = x & 1, and step 3 can be simplified to x = x >> 1.

Solution with reverse:

#include <string>
#include <algorithm>

std::string binary(unsigned x)
{
    std::string s;
    do
    {
        s.push_back('0' + (x & 1));
    } while (x >>= 1);
    std::reverse(s.begin(), s.end());
    return s;
}

Solution without reverse:

#include <string>

std::string binary(unsigned x)
{
    // Warning: this breaks for numbers with more than 64 bits
    char buffer[64];
    char* p = buffer + 64;
    do
    {
        *--p = '0' + (x & 1);
    } while (x >>= 1);
    return std::string(p, buffer + 64);
}

Upvotes: 15

Brian R. Bondy
Brian R. Bondy

Reputation: 347206

I assume this is related to your other question on extensible hashing.

First define some mnemonics for your bits:

const int FIRST_BIT = 0x1;
const int SECOND_BIT = 0x2;
const int THIRD_BIT = 0x4;

Then you have your number you want to convert to a bit string:

int x = someValue;

You can check if a bit is set by using the logical & operator.

if(x & FIRST_BIT)
{
    // The first bit is set.
}

And you can keep an std::string and you add 1 to that string if a bit is set, and you add 0 if the bit is not set. Depending on what order you want the string in you can start with the last bit and move to the first or just first to last.

You can refactor this into a loop and using it for arbitrarily sized numbers by calculating the mnemonic bits above using current_bit_value<<=1 after each iteration.

Upvotes: 1

Loki Astari
Loki Astari

Reputation: 264331

Try this:

#include <bitset>
#include <iostream>
int main()
{
    std::bitset<32>      x(23456);
    std::cout << x << "\n";


    // If you don't want a variable just create a temporary.
    std::cout << std::bitset<32>(23456) << "\n";
}

Upvotes: 44

user427390
user427390

Reputation:

There's a small header only library you can use for this here.

Example:

std::cout << ConvertInteger<Uint32>::ToBinaryString(21);
// Displays  "10101"

auto x = ConvertInteger<Int8>::ToBinaryString(21, true);
std::cout << x << "\n"; // displays "00010101"

auto x = ConvertInteger<Uint8>::ToBinaryString(21, true, "0b");
std::cout << x << "\n"; // displays "0b00010101"

Upvotes: 0

c4learn.com
c4learn.com

Reputation: 11

Use sprintf function to store the formatted output in the string variable, instead of printf for directly printing. Note, however, that these functions only work with C strings, and not C++ strings.

Upvotes: 0

ladookie
ladookie

Reputation: 1371

AND the number with 100000..., then 010000..., 0010000..., etc. Each time, if the result is 0, put a '0' in a char array, otherwise put a '1'.

int numberOfBits = sizeof(int) * 8;
char binary[numberOfBits + 1];
int decimal = 29;

for(int i = 0; i < numberOfBits; ++i) {
    if ((decimal & (0x80000000 >> i)) == 0) {
        binary[i] = '0';
    } else {
        binary[i] = '1';
    }
}
binary[numberOfBits] = '\0';
string binaryString(binary);

Upvotes: 2

Martin Beckett
Martin Beckett

Reputation: 96119

There isn't a direct function, you can just walk along the bits of the int (hint see >> ) and insert a '1' or '0' in the string.
Sounds like a standard interview / homework type question

Upvotes: 0

Related Questions