4

In visual studio on my PC I can use itoa() to convert from a base ten int to a base 2 c-string. However when I am on a Linux machine that function isn't supported. Is there another quick way of doing this kind of conversion? I know how to use a string stream and I can use the dividing and modding to convert to another base manually.

I was just hopping that there was an easier way of accessing the binary representation of an int.

Schuyler
  • 509
  • 1
  • 9
  • 19

4 Answers4

8

You could use std::bitset<N> with a suitable N (e.g., std::numeric_limits<int>::digits):

std::string bits = std::bitset<10>(value).to_string();

Note that ints just represent a value. They are certainly not base 10 although this is the default base used when formatting them (which can be easily change to octal or hexadecimal using std::oct and std::hex). If anything, ints are actually represented using base 2.

xinthose
  • 3,213
  • 3
  • 40
  • 59
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • It certainly should **not** be `sizeof(int) * CHAR_BIT`! We can freely use C++ and the proper spelling for this constant is `std::numeric_limits::digits` (note that my response already mentions that value). I haven't used it, however, because `std::bitset` will use `N` bits which is often not what you want. The `10` used is, of course, a random value which should probably be adjusted as required, e.g., to the the maximum number of bits stored in the actual value (which I think is `64` for `int` on typically Linuxes by default). – Dietmar Kühl Jul 13 '13 at 18:29
  • Oops -- I was thinking `digits` represented the number of decimal digits, but looking again that's actually `digits10`. My mistake. – Jerry Coffin Jul 13 '13 at 18:33
  • I get `Error: namespace "std" has no member "bitset"` with this answer. – starbeamrainbowlabs Nov 30 '15 at 14:18
  • 1
    @starbeamrainbowlabs: you'll need to include `` – Dietmar Kühl Nov 30 '15 at 14:40
1

The most straightforward solution for the C++ string:

std::string to_bin(unsigned int value) {
  if (value == 0) return "0";
  std::string result;
  while (value != 0) {
    result += '0' + (value & 1);
    value >>= 1;
  }
  std::reverse(result.begin(), result.end());
  return result;
}

For different bases (2 <= base <= 36):

std::string to_base(unsigned int value, int base) {
  if (value == 0) return "0";
  std::string result;
  while (value != 0) {
    int digit = value % base;
    result += (digit > 9 ? 'A' + digit - 10 : digit +'0');
    value /= base;
  }
  std::reverse(result.begin(), result.end());
  return s;
}

edit: fixed for negative numbers by changing argument from int to unsigned int

sasha.sochka
  • 14,395
  • 10
  • 44
  • 68
1

Same in C:

short UtilLitoa(long value, char* str, short base);
void UtilStrReverse(char* begin, char* end);
static const char c36Digits[] =  "0123456789abcdefghijklmnopqrstuvwxyz";

short UtilLitoa(long value, char* str, short base)
 {  
  char* wstr=str;
  int sign;
  unsigned long res;
  /* Validate base */
  if (base<2 || base>36)
   {
    if(str!=NULL)
     *str='\0';
    return(0);
   }
  /* Take care of sign */
  if ((sign=value) < 0)
   value = -value;
  res=value;
  /* Conversion. Number is reversed */
  do
   {
    value=(long)res;
    res=res/base;
    if(str!=NULL)
     *wstr = c36Digits[(unsigned long)value-res*base];
    wstr++;
   }
  while(res);
  if(sign<0)
   *wstr++='-';
  *wstr='\0';
  /* Reverse string */
  UtilStrReverse(str, wstr-1);
  return(wstr-str);
 }

void UtilStrReverse(char* begin, char* end)
{
  char aux;

  if(begin==NULL)
   return;
  if(end==NULL)
   end=begin+strlen(begin)-1;
  while(end>begin)
   {
    aux=*end;
    *end--=*begin;
    *begin++=aux;
   }    
}
Djee
  • 429
  • 3
  • 9
0

Yet another version

#include <string>
#include <limits>
#include <iostream>

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

template <class Number> void toBinaryRepresentation(
    const Number& n,
    std::string& str,
    const bool reverse = false)
{
    std::size_t i,j; // iterators
    const std::size_t numbits = std::numeric_limits<unsigned char>::digits;
    const char *raw = reinterpret_cast<const char*>(&n);
    str.resize(sizeof(n) * numbits);
    for (i = 0; i != sizeof(n); ++i)
    {
        for (j = 0; j < numbits; ++j)
        {
            str[i * numbits + j] = ((raw[i] >> j) & 1) + 48;
        }
    }
    if (reverse == false) std::reverse(str.begin(), str.end());
}

int main(int argc, char *argv[]) {
    if (argc != 3)
    {
        std::cerr << "Usage: " << argv[0];
        std::cerr << " [int|long|float] [number]" << std::endl;
        return -1;
    }
    #define test_start(type, from_string_to_type)          \
        if (std::strcmp(argv[1], TOSTRING(type)) == 0) {   \
            const type num = from_string_to_type(argv[2]); \
            toBinaryRepresentation(num, binary);           \
            std::cout << binary << std::endl;              \
        }

    #define test(type, from_string_to_type)                   \
        else if (std::strcmp(argv[1], TOSTRING(type)) == 0) { \
            const type num = from_string_to_type(argv[2]);    \
            toBinaryRepresentation(num, binary);              \
            std::cout << binary << std::endl;                 \
        }
    std::string binary;
    test_start(int, std::atoi)
    test(long, std::atol)
    test(float, std::atof)
    #undef test_start
    #undef test
    return 0;
}
rwols
  • 2,968
  • 2
  • 19
  • 26