#c #bit-manipulation #concatenation #bitwise-operators
#c #битовая манипуляция #конкатенация #побитовые операторы
Вопрос:
Я пытаюсь отправить сообщение через LPWAN, и одна из проблем, с которыми я сталкиваюсь, — это попытка сделать мое сообщение как можно короче.
Например:
У меня есть два целых числа (0-100) и два логических значения, которые я должен преобразовать в шестнадцатеричное значение для отправки через LPWAN. Пример:
- 24
- 63
- Верно
- Ложь
Когда я объединяю это как 246310 (Hex:3C226), это займет 3 байта. Однако я знаю, что мое первое целое число никогда не будет больше 50, то есть всего 6 бит. Могу ли я сделать шестнадцатеричное сообщение короче, чем 3C226?
Комментарии:
1. @LPs Они всегда состоят из 2 целых чисел и 2 логических значений, первое целое число всегда равно от 0 до 50, а второе целое число всегда от 0 до 100
2. В своем комментарии вы указываете, что второе целое число находится в диапазоне [0, 100], но в вашем вопросе это [0, 80]. Пожалуйста, отредактируйте свой вопрос, если он на самом деле [0, 100].
3. Кроме того, если между этими переменными нет каких-либо зависимостей, вам всегда будут нужны по крайней мере
ceil(log(51 * 101 * 2 * 2) / log(2)) = 15
биты для отправки этих сообщений. ответ unwind в этом случае максимально эффективен, и с ним также довольно легко работать.4. сделано, хотя это не имеет значения для вопроса, поскольку 100 равно 7 битам, как и 80
5. Это почти изменило ситуацию. Если у вас есть диапазоны [0, 50], [0, 79], [0, 1], [0, 1], вам понадобится не менее 14 бит, если вы используете другую технику.
Ответ №1:
Да, это должно быть возможно.
Количество битов для ваших полей равно:
integer0
: Целое число 0..50, 6 бит.integer1
: Целое число 0..80, 7 бит.flag0
: Логическое значение, 1 бит.flag1
: Логическое значение, 1 бит.
Таким образом, это в общей сложности 6 7 1 1 = 15 бит.
Вот как кодировать:
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
| | | | | |
| | integer0 | integer1 |f0|f1|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
uint16_t encode(uint8_t integer0, uint8_t integer1, bool flag0, bool flag1)
{
return ((uint16_t) integer0 << 9) | ((uint16_t) integer1 << 2) | ((uint16_t) flag0 << 1) | flag1;
}
Ответ №2:
Используя 2 байта, значение может быть сохранено в виде:
FirstNum Second 1st bool 2nd bool
<------------> <------------> <------------> <------------>
6bits 7bits 1bit 1bit
У вас все еще остается 1 бит.
Используйте left shift
операцию << для достижения вышеуказанного.