Я пытаюсь преобразовать строку двоичных чисел со знаком в десятичное значение в C ++, используя Stoi, как показано ниже.
stoi( binaryString, nullptr, 2 );
Мои входные данные представляют собой двоичную строку в формате 2s, и Stoi будет работать нормально, если количество цифр равно восьми. например, «1100» приводит к 12, потому что стои, вероятно, воспринимает его как «00001100».
Но для 4-битной системы 1100 в формате 2s равно -4. Любые подсказки, как сделать этот вид преобразования для чисел произвольной длины 2s в C ++?
Обработка сигнатур для чисел с меньшим количеством битов:
.
#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
,
Вы, вероятно, можете реализовать
в С ++, где a
является binaryString
, N
является binaryString.size()
а также w
это результат.
Правильный ответ, вероятно, будет зависеть от того, что вы в конечном итоге захотите сделать с int после преобразования. Если вы хотите выполнить математику со знаком, то вам нужно «подписать расширение» вашего результата после преобразования «стои» — это то, что компилятор делает внутренне для операции приведения из одного размера со знаком 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;
Вы можете использовать файл заголовка 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, вы должны проверить последний бит.