kona
kona

Reputation: 143

n bit 2s binary to decimal in C++

I am trying to convert a string of signed binary numbers to decimal value in C++ using stoi as shown below.

 stoi( binaryString, nullptr, 2 );

My inputs are binary string in 2s format and stoi will work fine as long as the number of digits is eight. for instance "1100" results 12 because stoi probably perceive it as "00001100".

But for a 4 bit system, 1100 in 2s format equals to -4. Any clues how to do this kind of conversion for arbitrary bit length 2s numbers in C++?

Upvotes: 3

Views: 2097

Answers (5)

himanshu shekhar
himanshu shekhar

Reputation: 190

you can use the bitset header file for this :

#include <iostream>
#include <bitset>
using namespace std;

int main()
{
    bitset<4> bs;
    int no;
    cin>>bs;
    if(bs[3])
    {
        bs[3]=0;
        no=-1*bs.to_ulong();
    }
    else
        no=bs.to_ulong();
    cout<<no;
    return 0;
}

Since it returns unsigned long so you have to check the last bit.

Upvotes: 1

Nicholaz
Nicholaz

Reputation: 1429

Handle sigendness for numbers with less bits:

  • convert binary -> decimal
  • calc 2s-complement if signed bit is set (wherever your sign bit is depending on wordlength).

.

#define BITSIZE 4
#define SIGNFLAG (1<<(BITSIZE-1)) // 0b1000
#define DATABITS (SIGNFLAG-1)     // 0b0111

int x= std::stoi( "1100", NULL, 2);  // x= 12 
if ((x & SIGNFLAG)!=0) {        // signflag set
    x= (~x & DATABITS) + 1;     // 2s complement without signflag
    x= -x;                      // negative number
}
printf("%d\n", x);              // -4

Upvotes: 4

Baratong
Baratong

Reputation: 101

The correct answer would probably depend on what you ultimately want to do with the int after you convert it. If you want to do signed math with it then you would need to 'sign extend' your result after the stoi conversion -- this is what the compiler does internally on a cast operation from one size signed int to another.

You can manually do this with something like this for a 4-bit system:

int myInt;

myInt = std::stoi( "1100", NULL, 2);

myInt |= myInt & 0x08 ? (-16 ) : 0;

Note, I used 0x08 as the test mask and -16 as the or mask as this is for a 4-bit result. You can change the mask to be correct for whatever your input bit length is. Also using a negative int like this will correctly sign-extend no matter what your systems integer size is.

Example for arbitrary bit width system (I used bitWidth to denote the size:

myInt = std::stoi( "1100", NULL, 2);

int bitWidth    = 4;

myInt |= myInt &  (1 << (bitWidth-1))  ? ( -(1<<bitWidth) ) : 0;

Upvotes: 1

Collin Dauphinee
Collin Dauphinee

Reputation: 13973

You can use strtoul, which is the unsigned equivalent. The only difference is that it returns an unsigned long, instead of an int.

Upvotes: 2

cubuspl42
cubuspl42

Reputation: 8380

You probably can implement

this

in C++, where a is binaryString, N is binaryString.size() and w is result.

Upvotes: 1

Related Questions