Разбить int на шестнадцатеричный уровень в C? - PullRequest
1 голос
/ 02 июля 2019

Я пытаюсь извлечь некоторые цветовые коды из буфера изображения. Когда я считываю адрес памяти из буфера, он возвращает значение int, которое содержит цветовые коды двух пикселей. Моя цель - получить каждый цветовой код в виде отдельного значения int.

Например, когда я считываю адрес памяти из буфера изображения, он возвращает десятичное значение: 142149753.

Поскольку это десятичное значение длиной 9 символов, я не могу просто разбить его на два значения типа int. Поэтому я попытался преобразовать значение в шестнадцатеричное с помощью функции printf, которая дала мне значение: 08790879.

Теперь я вижу два нужных мне 16-битных цветовых кода: 0879 и 0879.

int firstColorCode;
int secondColorCode;

int colorcodes = IORD_ALTERA_AVALON_PIO_DATA(0x08000000 + 123204);

printf("%08x\n", colorcodes);

Как я могу получить два цветовых кода в соответствующие переменные int в коде?

Отказ от ответственности: я новичок в C, и мне кажется, что я задаю глупый вопрос: /

Ответы [ 3 ]

2 голосов
/ 02 июля 2019

Вам нужно использовать сдвиг вправо, чтобы получить первый цветовой код.Для второго цветового кода необходимо либо маскировать, либо вводить тип с помощью uint16_t

firstColorCode = (uint16_t) (colorcodes >> 16u);
secondColorCode = (uint16_t) colorcodes;

. Вы также можете использовать

firstColorCode = (colorcodes >> 16u) & 0xFFFFu;
secondColorCode = colorcodes & 0xFFFFu;

. Для цветовых кодов следует использовать значения типа unsigned int, чтобыизбегать неопределенного поведения в правильных сменах.

uint16_t firstColorCode;
uint16_t secondColorCode;
uint32_t colorcodes; 

Также, как подсказал @lundin, я добавил u к константам, чтобы сделать их константами без знака.

0 голосов
/ 03 июля 2019

Просто разделите число на 65536.Остальная часть будет нижней частью вашей половины, а частная - наиболее значимой частью.

Кстати, идея некоторых комментариев по работе со значениями без знака также хороша, и учтите, что смещение вправо на unsigned intчисло на 16 является эквивалентом деления на 2^16 == 65536.

0 голосов
/ 02 июля 2019

Существуют некоторые основные правила при обходе минного поля системы типов C:

  • Никогда не используйте подписанные типы при выполнении любых побитовых манипуляций.
  • Никогда не используйте подписанные типы, когда вы не используетена самом деле не нужны отрицательные числа.
  • Будьте осторожны при использовании небольших целочисленных типов, таких как char, short, uint16_t и т. д., поскольку они неявно повышаются до int при использовании в выражении.
    Больше информации о неявных продвижениях: Правила неявного продвижения типов
  • Остерегайтесь шестнадцатеричных литералов, потому что у них есть различные тонкие правила относительно того, какой тип они получают.Всегда добавляйте к ним суффикс u, чтобы они не были подписанным типом.
  • Никогда не пишите начальные нули в C-коде.Если вы напишите что-то вроде 0879 на C, это означает восьмеричный формат.

Заботясь о типах, мы можем разделить ваше 32-битное число на две части, например:

#include <stdint.h>

uint16_t first;
uint16_t second;

uint32_t colorcodes = IORD_ALTERA_AVALON_PIO_DATA(0x8000000u + 123204u);

first = (uint16_t) (colorcodes >> 16);
second = (uint16_t) colorcodes;

Печать uint16_t в шестнадцатеричном виде с использованием printf("%"PRIx16, first), от inttypes.h.

...