14

Why does bitset store the bits in reverse order? After strugging many times I have finally written this binary_to_dec. Could it simplified?

int binary_to_dec(std::string bin)
{
    std::bitset<8> bit;

    int c = bin.size();

    for (size_t i = 0; i < bin.size(); i++,c--)
    {
        bit.set(c-1, (bin[i]-'0' ? true : false));
    }

    return bit.to_ulong();
}
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
user4344
  • 661
  • 3
  • 8
  • 16
  • For example: `std::string bin = "1011"` but bitset requires it to be in order `"1101"` – user4344 Feb 11 '11 at 23:24
  • 2
    bitset doesn't store the bits in "reverse" order. Your input string does, however. – Jeremy CD Feb 11 '11 at 23:26
  • 2
    `bitset` doesn't "require" anything! It is basically just an array, and `to_ulong()` simply calculates `bit[0]*2^0 + bit[1]*2^1 + bit[2]*2^2 + ..." (where `^` denotes "to-the-power-of"). – Oliver Charlesworth Feb 11 '11 at 23:27
  • 1
    Related: [Why does `bitset` expose bits in little-endian fashion?](http://stackoverflow.com/q/29483123/183120) – legends2k Apr 08 '15 at 01:19

2 Answers2

34

Bitset stores its numbers in what you consider to be "reverse" order because we write the digits of a number in decreasing order of significance even though the characters of a string are arranged in increasing index order.

If we wrote our numbers in little-endian order, then you wouldn't have this confusion because the character at index 0 of your string would represent bit 0 of the bitset. But we write our numbers in big-endian order. I'm afraid I don't know the details of human history that led to that convention. (And note that the endianness that any particular CPU uses to store multi-byte numbers is irrelevant. I'm talking about the endianness we use when displaying numbers for humans to read.)

For example, if we write the decimal number 12 in binary, we get 1100. The least significant bit is on the right. We call that "bit 0." But if we put that in a string, "1100", the character at index 0 of that string represents bit 3, not bit 0. If we created a bitset with the bits in the same order as the characters, to_ulong would return 3 instead of 12.

The bitset class has a constructor that accepts a std::string, but it expects the index of the character to match the index of the bit, so you need to reverse the string. Try this:

int binary_to_dec(std::string const& bin)
{
  std::bitset<8> bit(std::string(bin.rbegin(), bin.rend()));
  return bit.to_ulong();
}
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
2
unsigned long binary_to_dec(std::string bin)
{
    std::bitset<sizeof(unsigned long)*8> bits(bin);
    return bits.to_ulong();
}

EDIT: formatting and return type.

Jeremy CD
  • 597
  • 4
  • 10