Reputation: 19
I have a problem converting a string binary to a decimal
I was using bitset
bitstring ="1011010001111111";
unsigned long binToDec( string bitstring){
bitset<32> dec (bitstring);
return dec.to_ulong();
}
All of this works fine, but !! the problem comes when i try to do the same with a bits string with more of 32 bits. I know that bitset only does the conversion with 4 bytes, but i need to do the conversion with strings that has 48 or 56 bits (sometimes i need to get 14 or 15 digits )
string bitstring;
bitstring ="11100101001001000000100000100100110100110011010001111111";
i want to get this number: 64497387062899840
Any sugestion? anybody have a function to transform a binary string to decimal ?
Note: i can´t use boost because it´s not ported to the iphone.
Thanks for your help
Upvotes: 5
Views: 2330
Reputation: 79930
I've just put together this and it seems to work with your example, I haven't tested any bigger values, compared result with calculator.
Outputs:
64497387062899839
Code:
#include <iostream>
#include <limits>
using namespace std;
unsigned long long convert(string& bits)
{
if (bits.length() > (size_t)numeric_limits<unsigned long long>::digits)
return 0;
unsigned long long sum = 0;
unsigned long long shift = 1;
for (string::reverse_iterator it(bits.rbegin()), end(bits.rend());
it < end; ++it)
{
if (*it == '1') sum += shift;
shift = (shift << 1);
}
return sum;
}
int main()
{
string bits("11100101001001000000100000100100110100110011010001111111");
cout << "returned: " << convert(bits) << endl;
}
Upvotes: 1
Reputation: 111316
You are probably hitting overflow whenever you cross ULONG_MAX
. Use a bigger data type such as unsigned long long
. However, if your number can be larger than the max this type can hold, you are probably looking at having to implement a bignum library.
Following cube's suggestion, vanilla C code:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
uint64_t binToDec(const char * s){
uint64_t res = 0; size_t i, n;
for (i = 0, n = strlen(s) - 1; i < n; ++i) {
res = (res | (unsigned int)(s[ i ] - '0')) << 1;
}
return res;
}
int main() {
/* Note the special C99 format specifier macros defined in <inttypes.h> */
printf("%"PRIu64"\n",
binToDec("11100101001001000000100000100100110100110011010001111111"));
}
Note: ISO C++ does not support long long
.
Upvotes: 2
Reputation: 54300
This should do the trick, but is untested.
unsigned long binToDec(const std::string& s)
{
unsigned long d = 0;
for (int i = 0; i < s.size(); ++i)
{
d <<= 1;
if (s[i] == '1')
++d;
}
return d;
}
Upvotes: 1
Reputation: 11782
The simplest answer would be to chop your string in half, convert it to a pair of 32bit ints and then pack them together.
Upvotes: 1