Как закодировать 3 целочисленных значения в uint16_t с помощью побитовых операций? - PullRequest
2 голосов
/ 05 августа 2020

Я хочу сохранить 3 целых числа без знака в переменной uint16_t, выполнив побитовые операции, и прочитать их обратно, используя побитовые операции. Вот моя программа для этого:

Код:

#include <iostream>

uint16_t Write(unsigned int iVal1, unsigned int iVal2, unsigned int iVal3) {
    // iVal1 should go into the first 8 bits [iVal1 value ranges from 0 to 173]
    // iVal2 should go into the 6 bits after that [iVal2 value ranges from 0 to 63]
    // iVal3 should go into the 2 bits after that [iVal3 value ranges from 0 to 3]
    // Is the below way of writing the bits correct?
    return (static_cast<uint16_t>(iVal1)<<8) + (static_cast<uint16_t>(iVal2)<<6) + (static_cast<uint16_t>(iVal3)<<2);
}

unsigned int ReadVal1(const uint16_t theNumber) {
    // ival1 is the first 8 bits
    uint16_t check1 = 255;
    return (theNumber>>8)&check1;
}

unsigned int ReadVal2(const uint16_t theNumber) {
    // ival2 is the 6 bits after that
    uint16_t check2 = 63;
    return (theNumber>>3)&check2;
}

unsigned int ReadVal3(const uint16_t theNumber) {
    // ival3 is the last 2 bits
    uint16_t check3 = 3;
    return (theNumber>>1)&check3;
}

int main() {
    std::cout << "Main started" << std::endl;

    unsigned int iVal1 = 191;
    unsigned int iVal2 = 28;
    unsigned int iVal3 = 3;

    const uint16_t theNumber = Write(iVal1, iVal2, iVal3);

    std::cout << "The first 8 bits contain the number: " << ReadVal1(theNumber) << std::endl;
    std::cout << "Then after 6 bits contain the number: " << ReadVal2(theNumber) << std::endl;
    std::cout << "Then after 2 bits contain the number: " << ReadVal3(theNumber) << std::endl;
}

В приведенной выше программе ниже приведены диапазоны трех целых чисел без знака, которые необходимо закодировать.

`iVal1` ranges from `0 to 173`. So its well within 8 bits.
`iVal2` ranges from `0 to 63`. So its well within 6 bits.
`iVal3` ranges from `0 to 3`. So its well within 2 bits.

Вопрос: Я думаю, что я неправильно пишу значения внутри функции Write. Каков правильный способ?

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

Я считаю, что мой способ чтения значений в функциях ReadVal1, ReadVal2 и ReadVal3 правильный. Я понял, как легко считывать значения. Но я не мог хорошо понять logi c того, как правильно кодировать значения с помощью побитовых операций.

Компилятор C ++: Я использую C ++ 11 компилятор

1 Ответ

2 голосов
/ 05 августа 2020

Количество битов для сдвига целого числа не должно зависеть от размера сдвигаемого целого числа, а от размера всех целых чисел, которые идут после него (вправо). Вот некоторые символы ASCII для иллюстрации принципа:

                                +---+---+---+---+---+---+---+---+
                                ‖i1 |i1 |i1 |i1 |i1 |i1 |i1 |i1 ‖ 8 bit
                                ‖ 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 ‖
                                +---+---+---+---+---+---+---+---+
                                 _______________________________/
                                /                     
                                |       +---+---+---+---+---+---+
                                |       ‖i2 |i2 |i2 |i2 |i2 |i2 ‖ 6 bit
                                |       ‖ 5 | 4 | 3 | 2 | 1 | 0 ‖
                                |       +---+---+---+---+---+---+
                                |                       ________/
                                |                      /
                                |                      |+---+---+
                                |                      |‖i3 |i3 ‖ 2 bit
                                |                      |‖ 1 | 0 ‖
                                |                      |+---+---+
                                |                      \        |
                                |<<(6+2)                |<<2    |<<0
                                v                       v       v
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
‖ F | E | D | C | B | A | 9 | 8 ‖ 7 | 6 | 5 | 4 | 3 | 2 ‖ 1 | 0 ‖
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
‖i1 |i1 |i1 |i1 |i1 |i1 |i1 |i1 ‖i2 |i2 |i2 |i2 |i2 |i2 ‖i3 |i3 ‖
‖ 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 ‖ 5 | 4 | 3 | 2 | 1 | 0 ‖ 1 | 0 ‖
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
...