Как замаскировать первые 2 байта MSB 64-битного числа? - PullRequest
2 голосов
/ 11 июля 2019

У меня есть 64-bit unsigned integer. Который содержит 0s в первых двух байтах MSB. Как я могу замаскировать эти первые два байта MSB?

uint64 value;
value = 0000 0000 0000 0000 0000 1101 1111 1010 1110 1111 1111 1111 0101 
0101 1101 1101;
uint48 answer;
answer = 0000 1101 1111 1010 1110 1111 1111 1111 0101 
0101 1101 1101;

В приведенном выше примере значение является 64-разрядным числом. Я хочу, чтобы ответ содержал все биты, кроме первых 2 байтов. Таким образом, я могу упаковать answer в байтовый массив размером 6. Как я могу добиться этого в C?

Ответы [ 3 ]

3 голосов
/ 11 июля 2019

Маска с 48 однобитными: 0xffffffffffff

uint64_t value = <something>;
uint48_t answer = src & 0xffffffffffff;

Но если вы знаете, что 2 MSB равны нулю, вам не нужно делать никаких маскировок, просто присвойте переменные:

uint48_t answer = value;

Чтобы сохранить их в байтовом массиве, сдвиньте на соответствующее количество байтов и замаскируйте с помощью 0xff, чтобы получить один байт.

uint8_t bytes[6];
for (int i = 0; i < 6; i++) {
    bytes[i] = (value >> (40 - 8 * i)) & 0xff;
}

Вы можете использовать либо оригинальное 64-битное значение, либо 48-битное значение, это работает для любого размера не менее 6 байтов.

1 голос
/ 11 июля 2019
void *copt6lsb(uint64_t val, void *buff)
{
    union{
        uint8_t d8[2];
        uint16_t d16;
    }u16 = {.d8[0] = 0xff};
    char *pos = &val;

    pos = pos + 2 * (u16.d16 == 0xff00);
    memcpy(buff, pos, 6);
    return buff;
}

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

https://godbolt.org/z/JKXDC2

и платформы, которые разрешают доступ без выравнивания, также оптимизируют memcpy

https://godbolt.org/z/c3_ypL

1 голос
/ 11 июля 2019

Создайте объединение со своим значением uint64_t и массивом байтов.

typefef union
{
    uint8_t   ByteArray[8];
    uint64_t  Value;
}Array64T;

Array64T   CompleteValue;

CompleteValue.Value = ...
...