我正在尝试使用 stoi 将一串有符号二进制数转换为 C++ 中的十进制值,如下所示。
stoi( binaryString, nullptr, 2 );
我的输入是 2s 格式的二进制字符串,只要位数为 8,stoi 就可以正常工作。例如“1100”结果为 12,因为 stoi 可能将其视为“00001100”。
但是对于 4 位系统,2s 格式的 1100 等于 -4。任何线索如何在 C++ 中对任意位长度 2s 数字进行这种转换?
我正在尝试使用 stoi 将一串有符号二进制数转换为 C++ 中的十进制值,如下所示。
stoi( binaryString, nullptr, 2 );
我的输入是 2s 格式的二进制字符串,只要位数为 8,stoi 就可以正常工作。例如“1100”结果为 12,因为 stoi 可能将其视为“00001100”。
但是对于 4 位系统,2s 格式的 1100 等于 -4。任何线索如何在 C++ 中对任意位长度 2s 数字进行这种转换?
处理位数较少的数字的重要性:
.
#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
您可以使用strtoul
,它是无符号的等价物。唯一的区别是它返回一个unsigned long
,而不是一个int
。
您可以为此使用 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 所以你必须检查最后一位。
正确的答案可能取决于您在转换后最终想要对 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;
您可能可以实施
在 C++ 中,其中a
is binaryString
、N
isbinaryString.size()
和w
is 结果。