C++中n位二进制2s补码转换为十进制

3
我正在尝试使用C ++中的stoi将一串有符号二进制数转换为十进制值,如下所示。
 stoi( binaryString, nullptr, 2 );

我的输入是2s格式的二进制字符串,如果数字位数为8,则stoi函数可以正常工作。例如,“1100”会得到12,因为stoi函数可能将其视为“00001100”。
但对于4位系统,2s格式中的1100等于-4。有什么方法可以在C++中实现任意位数的2s格式数字转换吗?

4
如果高位为1,使用二进制补码表示?那么可以使用~val和-1或者- val来实现。 - Michael Dorgan
5个回答

4

处理比特数较少的数字的有符号位:

  • 将二进制转换为十进制
  • 如果设置了有符号位(根据字长确定其位置),计算2的补码。

.

#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

2

您可以使用strtoul函数,它是无符号类型的等效函数。唯一的区别是它返回一个unsigned long而不是一个int


1
正确的答案可能取决于您在转换后最终想要做什么。如果您想使用有符号数进行数学计算,则需要在 stoi 转换后“符号扩展”您的结果 - 这是编译器在从一个大小带符号 int 转换到另一个大小时内部执行的操作。
您可以手动使用以下内容在 4 位系统中执行此操作:
int myInt;

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

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

注意,我使用0x08作为测试掩码,使用-16作为或掩码,因为这是4位结果。您可以根据输入位长度更改掩码以正确匹配。此外,像这样使用负整数将始终正确地进行符号扩展,无论您的系统整数大小如何。
任意位宽系统的示例(我使用bitWidth表示大小:
myInt = std::stoi( "1100", NULL, 2);

int bitWidth    = 4;

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

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

由于其返回无符号长整型,因此您需要检查最后一位。


1

您可能可以实现

this

在C++中,其中abinaryStringNbinaryString.size()w是结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接