Преобразование двух дополняющих выводов в знаковое десятичное число

Я прошу прощения, если на этот вопрос уже был дан ответ, но я не смог найти то, что я ищу.

Я работаю в C ++ с устройством SPI. Устройство SPI выводит данные в 16-битных словах в виде дополнения 2. Я пытаюсь преобразовать эти данные в десятичную для использования с фильтром.

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

#include <iostream>
#include <stdlib.h>
#include <cstdint>
#include <cmath>
#include <bitset>
using std::cout;
using std::endl;
using std::cin;
using std::hex;
using std::dec;
using std::bitset;
int main () {
uint16_t x2=0;
cout<<"Please enter the number you would like to convert from 2's complement.  "<<endl;
cin>>x2;
int diff=0x0000-x2;
cout<<"The number you have entered is: "<<dec<<diff<<endl;
return 0;
}

Когда я запускаю эту программу и вводю что-то вроде 0x3B4A, она всегда выдает 0. Я не совсем уверен, что происходит, и я очень плохо знаком с c ++, поэтому, пожалуйста, извините, если это глупый вопрос. Также, пожалуйста, игнорируйте что-нибудь лишнее в шапке. Это часть большого проекта, и я не мог вспомнить, какие части заголовка идут с этим конкретным разделом кода.

Спасибо!

Изменить: Это в основном для Бена. Прочитав ваш последний комментарий, я внес следующие изменения, но все еще просто получаю десятичный эквивалент введенного мною шестнадцатеричного числа.

#include <iostream>
#include <stdlib.h>
#include <cstdint>
#include <cmath>
#include <bitset>
using std::cout;
using std::endl;
using std::cin;
using std::hex;
using std::dec;
using std::bitset;
int main () {
int16_t x2=0;
cout<<"Please enter the number you would like to convert from 2's complement.  "<<endl;
cin>>hex>>x2;
int flags= (x2>>14) & 3;
int16_t value=(x2 << 2) >> 2;
cout<<"The number you have entered is: "<<dec<<value<<endl;
return 0;
}

1

Решение

Стандартная функция библиотеки strtol преобразует строковый ввод в число и поддерживает 0x префикс, пока вы проходите 0 как основополагающий аргумент.

поскольку int16_t почти наверняка подписано 16-битное дополнение два, вы можете просто использовать это.

0

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

Вы попросили cin читать как десятичное число (не внося изменений в формат), чтобы, как только он прочитал x, который не является цифрой 0-9, он останавливался, оставляя вас с нулем.

Просто добавь hex на вашу линию cin: cin >> hex >> x2;

2

Я не уверен, что это необходимо для вопроса ОП, но для любого, кто просто ищет формулу для преобразования 16-разрядного целого числа без знака в 2-битном виде в целое число со знаком, я думаю, что вариант этого выглядит так (для ввода val):

(0x8000&val ? (int)(0x7FFF&val)-0x8000 : val)

Это составляет:

  • если первый бит равен 1, это отрицательное число со всеми остальными битами в дополнении 2
  • извлечь отрицательную часть, вычитая из 0x8000
  • в противном случае младшие биты являются просто положительным целым значением

Вероятно, это хорошая идея, чтобы обернуть это в функцию и выполнить некоторую базовую проверку ошибок (также можно убедиться, что входные данные на самом деле представляют собой 16-разрядное целое число без знака).

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