在C ++中n位二进制到十进制

时间:2013-06-05 18:01:02

标签: c++ binary decimal twos-complement

我正在尝试使用stoi将一串带符号的二进制数转换为C ++中的十进制值,如下所示。

 stoi( binaryString, nullptr, 2 );

我的输入是2s格式的二进制字符串,只要位数为8,stoi就可以正常工作。例如“1100”结果12因为stoi可能将其视为“00001100”。

但对于4位系统,1100s 2s格式等于-4。有什么线索如何在C ++中对任意位长2s数进行这种转换?

5 个答案:

答案 0 :(得分:4)

处理位数较少的数字的sigendness:

  • 转换二进制 - >小数
  • calc 2s-complement如果设置了signed bit(符号位取决于字长)。

#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

答案 1 :(得分:2)

您可以使用strtoul,这是无符号的等效项。唯一的区别是它返回unsigned long,而不是int

答案 2 :(得分:1)

您可能可以实施

this

在C ++中abinaryStringNbinaryString.size()w为结果。

答案 3 :(得分:1)

正确答案可能取决于转换后你最终想要对int做什么。如果你想用它进行带符号的数学运算,那么你需要在stoi转换后对符号进行“签名扩展” - 这就是编译器在内部执行从一个大小的符号int到另一个大小的转换操作。

对于4位系统,您可以手动执行此操作:

int myInt;

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

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

注意,我使用0x08作为测试掩码,使用-16作为掩码,因为这是4位结果。无论输入的位长是多少,您都可以将掩码更改为正确。无论你的系统整数大小是什么,使用像这样的负int将正确地签名扩展。

任意位宽系统的示例(我使用bitWidth来表示大小:

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

int bitWidth    = 4;

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

答案 4 :(得分:1)

您可以使用bitset头文件:

#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;
}

因为它返回unsigned long所以你必须检查最后一位。