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

Я работаю на С ++ с устройством 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
Andrew L 8 Апр 2014 в 23:23

3 ответа

Лучший ответ

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

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

0
Ben Voigt 8 Апр 2014 в 19:43

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

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

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

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

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

4
sage 23 Июл 2014 в 23:21

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

Просто добавьте hex в строку cin: cin >> hex >> x2;

2
Mark B 8 Апр 2014 в 19:32