n бит 2 с двоичного в десятичное в переполнении стека

Я пытаюсь преобразовать строку двоичных чисел со знаком в десятичное значение в C ++, используя Stoi, как показано ниже.

 stoi( binaryString, nullptr, 2 );

Мои входные данные представляют собой двоичную строку в формате 2s, и Stoi будет работать нормально, если количество цифр равно восьми. например, «1100» приводит к 12, потому что стои, вероятно, воспринимает его как «00001100».

Но для 4-битной системы 1100 в формате 2s равно -4. Любые подсказки, как сделать этот вид преобразования для чисел произвольной длины 2s в C ++?

2

Решение

Обработка сигнатур для чисел с меньшим количеством битов:

  • преобразовать двоичный код -> десятичный
  • calc 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
3

Другие решения

Ты можешь использовать strtoul, который является беззнаковым эквивалентом. Единственное отличие состоит в том, что он возвращает unsigned longвместо int,

2

Вы, вероятно, можете реализовать

этот

в С ++, где a является binaryString, N является binaryString.size() а также w это результат.

1

Правильный ответ, вероятно, будет зависеть от того, что вы в конечном итоге захотите сделать с 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;
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, вы должны проверить последний бит.

1
По вопросам рекламы [email protected]