При использовании комбинации масок и сдвигов:
int main()
{
const uint32_t v = 0x00870016;
const uint16_t major = (v & 0xFFFF0000) >> 16;
const uint16_t minor = v & 0x0000FFFF;
cout << major << "." << minor << "\n";
}
Выход:
135.22
Пояснение:
0x00870016
представляет собой 32-битное число. Ваш основной номер версии состоит из 16 наиболее значимых цифр, а младший номер версии - это 16 наименее значащих цифр.
Для извлечения основного номера версии, давайте выясним, что 16 MSBits является маскировка значения входного сигнала с 0xFFFF0000
- номером, по которому все 16 из наиболее signifigant цифр устанавливаются в 1
и все наималейшее сиг биты 0
:
0x00870016 && 0xFFFF0000 = 0x00870000
Полученное значение является вашим основным номером версии, сдвинут влево 16 бит. Поэтому давайте переместим его на:
0x00870000 >> 16 = 0x00000087
И вот у нас есть ваш настоящий номер главной версии.
Извлечение младшего номера версии аналогично, за исключением того, что нам не нужно сдвигать.
Примечание:
Первый шаг может быть упрощена путем пропуска маски:
const uint16_t major = v >> 16;
Это работает, потому что Стандарт C++ говорит, что, когда вы сдвиг вправо, освободившиеся биты заполняются 0
s. Таким образом, окончательная программа будет:
int main()
{
const uint32_t v = 0x00870016;
const uint16_t major = v >> 16;
const uint16_t minor = v & 0x0000FFFF;
cout << major << "." << minor << "\n";
}
Edit:
Как было отмечено в комментариях, вы можете получать 0x00870016
в виде строки, а не числа. Нам просто нужно преобразовать эту строку в числовой эквивалент.Работа с ведущими 0x
может показаться, как камень преткновения, но это не так, если вы используете C++ Standard Library iostream манипуляторов:
int main()
{
const std::string inVer = "0x00870016";
uint32_t v = 0;
std::stringstream ss;
ss << inVer;
ss >> std::hex >> v;
const uint16_t major = v >> 16;
const uint16_t minor = v & 0x0000FFFF;
cout << major << "." << minor << "\n";
}
OP получили версию в виде строки, Я думаю, было бы интересно добавить бит кода, который сначала преобразует его в интегральное значение ради полноты – SirDarius
@SirDarius: Согласовано и отредактировано. –
Не используйте здесь 'uint32_t' и' uint16_t': они переполнены, потому что ** не существуют ** в системах, которые не имеют таких точных размеров. Если код использует 'uint_least32_t' или' uint_fast32_t' или 'unsigned long', он будет работать так же хорошо, и не будет иметь этой переносимости. –