Я попал в ловушку, пытаясь упаковать пару переменных в одну переменную длиной 8 байт.
По сути, у меня есть несколько коротких элементов с небольшим двоичным размером, и мне нужно упаковать их вместе, чтобы отправить в класс, который должен иметь возможность распаковать его обратно.
Поэтому я сделал следующее:
typedef unsigned long long PACKAGE; // 8 byte (shows as _int64 in debug)
(sizeof returns '8')
unsigned int dat1 = 25; // 1 byte long max
unsigned int dat2 = 1; // 4 bit long max
unsigned int dat3 = 100; // 2 byte long max
unsigned int dat4 = 200; // 4 byte long max
unsigned int dat5 = 2; // 4 bit long max
Затем я создаю переменную типа PACKAGE, которая пуста (0)
PACKAGE pack = 0;
И я хочу добавить переменные в этот пакет, используя бинарные операции, я делаю:
pack = (dat1 << 56) | (dat2 << 52) | (dat3 << 36) | (dat4 << 4) | dat5;
это работает только наполовину, я посчитал, что я должен получить десятичное значение пакета, равное 2526526262902525058
, или
0010001100010000000001100100000000000000000000000000110010000010
как двоичный, однако вместо этого я получаю 588254914
или 00100011000100000000111011000010
как двоичный файл, который каким-то образом правильный в хвосте и голове, но где-то отсутствует средняя часть.
И когда это будет сделано, я все еще собираюсь каким-то образом извлечь данные обратно.
uint64_t
и структурой битового поля? Хотя подобная каламбуризация нарушает строгое правило алиасинга. - person Some programmer dude   schedule 03.08.2016int
странный зверь. В зависимости от компилятора он может иметь длину от 16 бит до, по крайней мере, 64 бит. Это делает его случайное переполнение относительно легким. Если ваш компилятор поддерживает их, попробуйте использовать целые числа фиксированной ширины. - person user4581301   schedule 03.08.2016dat1 << 56
, ноdat1
был объявлен какunsigned int
. Еслиunsigned int
на вашей платформе 32-битная, то это поведение undefined - если 64-битная, то все в порядке. - person Jesper Juhl   schedule 03.08.2016