Как расшифровать 4 короткие переменные из длинного, используя битовые манипуляции в C ++? - PullRequest
0 голосов
/ 18 января 2011
long wxyz; //(w = bits 0-8, x = bits 9-17 , y = bits 18-23, z =  bits 24-29)


short w;

short x;

short y;

short z;

w= wxyz & 0xFF800000;
x= wxyz & 0x007FC000;
y= wxyz & 0x00003F00;
z= wxyz & 0x000000FC;

Правильно ли указан этот код?

Спасибо

Ответы [ 7 ]

2 голосов
/ 18 января 2011

Вам нужно сдвинуть биты вниз.

w= (wxyz & 0xFF800000) >> 23;
x= (wxyz & 0x007FC000) >> 14;
y= (wxyz & 0x00003F00) >> 8;
z= (wxyz & 0x000000FC) >> 2;
1 голос
/ 18 января 2011
w =  wxyz & 0x000001ff;
x = (wxyz & 0x0003fe00) >> 9;
y = (wxyz & 0x00fc0000) >> 17;
z = (wxyz & 0x3f000000) >> 23;

Редактировать: нужно приводить длинные к коротким, чтобы избежать предупреждения компилятора:

w = (short) wxyz & 0x000001ff;
x = (short) ((wxyz & 0x0003fe00) >> 9);
y = (short) ((wxyz & 0x00fc0000) >> 17);
z = (short) ((wxyz & 0x3f000000) >> 23);
1 голос
/ 18 января 2011

Вы должны сделать следующее, чтобы получить старший байт из 4 байтов int w = (wxyz & 0xFF000000) >> 24. Сначала примените битовую маску, а затем сдвиньте биты на младший байт.

Или вы можете сделать это иначе - сдвинуть, применить битовую маску:

w = (wxyz >> 24) & 0xFF
x = (wxyz >> 16) & 0xFF
y = (wxyz >> 8) & 0xFF
z = wxyz & 0xFF

Но не проще ли использовать профсоюзы?

0 голосов
/ 18 января 2011

Вот другое решение, которое вы можете использовать.

long wxyz;
short w, x, y, z;
char* buf = new char[sizeof(long)];
buf = (char*)long; // cast long as byte array
w = (short)buf[0]; // The way you sort depends on endianness
x = (short)buf[1];
y = (short)buf[2];
z = (short)buf[3];
delete[] buf;
0 голосов
/ 18 января 2011

Это способ, которым я предпочитаю справляться с этим, "медленно". Это просто имеет больше смысла в моей голове. Кроме того, в отличие от маски и затем сдвига, не проблема в том, что >> расширяет знак (C / C ++ не является Java или C # в четкости там). Я исхожу из предположения, что 0 - это MSB (а всего 32 бита, хотя длинный может быть больше), как указано в вопросе.

long wxyz = ...; //(w = bits 0-8, x = bits 9-17 , y = bits 18-23, z =  bits 24-29)

wxyz >>= 2; // discard 30-31 (or, really, "least two insignificant")

z = wzyz & 0x3f; // easy to see this is "6 bits", no?
wzyz >>= 6; // throw them out

y = wzyz & 0x3f;
wzyz >>= 6;

x = wzyz & 0x1ff;
wzyz >>= 9;

w = wzyz & 0x1ff;
wzyz >>= 9; // for fun, but nothing consumes after

P.S. Настройка для типов оставлена ​​читателю в качестве упражнения.

0 голосов
/ 18 января 2011

Держись - что ты имеешь в виду под битами 0-8? Обычно это означает девять младших разрядов, и в этом случае вы взяли неверный конец целого.

0 голосов
/ 18 января 2011

Частично правильно.Вам нужно сдвинуть их вправо, если вы хотите значения каждого сегмента.

short w = (short)((wxyz & 0xFF800000) >> 23);
short x = (short)((wxyz & 0x007FC000) >> 14);
short y = (short)((wxyz & 0x00003F00) >> 8);
short z = (short)((wxyz & 0x000000FC) >> 2);

Это правильные значения.

...