n бит 2s двоично-десятичный в C++
Я пытаюсь преобразовать строку двоичных чисел со знаком в десятичное значение в C++, используя Stoi, как показано ниже.
stoi( binaryString, nullptr, 2 );
Мои входные данные представляют собой двоичную строку в формате 2s, и Stoi будет работать нормально, если количество цифр равно восьми. например, "1100" приводит к 12, потому что стои, вероятно, воспринимает его как "00001100".
Но для 4-битной системы 1100 в формате 2s равно -4. Любые подсказки, как сделать этот вид преобразования для чисел произвольной длины 2s в C++?
5 ответов
Обработка сигнатур для чисел с меньшим количеством битов:
- преобразовать двоичный код -> десятичный
- 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
Ты можешь использовать 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, вы должны проверить последний бит.