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;
Is this code correct?
Thanks
You need to shift the bits down.
w= (wxyz & 0xFF800000) >> 23;
x= (wxyz & 0x007FC000) >> 14;
y= (wxyz & 0x00003F00) >> 8;
z= (wxyz & 0x000000FC) >> 2;
You should do the following to get the highest byte from the 4 bytes int w = (wxyz & 0xFF000000) >> 24
. First apply bit mask and then shift bits to the lowest byte.
Or you can do it other way around - shift, apply bitmask:
w = (wxyz >> 24) & 0xFF
x = (wxyz >> 16) & 0xFF
y = (wxyz >> 8) & 0xFF
z = wxyz & 0xFF
But isn't it easier to use unions?
w = wxyz & 0x000001ff;
x = (wxyz & 0x0003fe00) >> 9;
y = (wxyz & 0x00fc0000) >> 17;
z = (wxyz & 0x3f000000) >> 23;
Edit: need to cast long to short to avoid compiler warning:
w = (short) wxyz & 0x000001ff;
x = (short) ((wxyz & 0x0003fe00) >> 9);
y = (short) ((wxyz & 0x00fc0000) >> 17);
z = (short) ((wxyz & 0x3f000000) >> 23);
Hold on -- what do you mean by bits 0-8? This usually means the nine least significant bits, in which case you've grasped the wrong end of the int.
This is the way I prefer to handle this, by "inching". It just makes more sense in my head. Also, unlike a mask and then shift, there is no problem of a >> being sign-extending (C/C++ isn't Java or C# in well-definedness there). I am going with the assumption that 0 is the MSB (and there are 32bits total, although a long can be more), as stated in the question.
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. Adjusting for types is left as an exercise to the reader.
Here's a different solution you can use.
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;
Partially correct. You'll have to shift them to the right if you want the values of each segment.
short w = (short)((wxyz & 0xFF800000) >> 23);
short x = (short)((wxyz & 0x007FC000) >> 14);
short y = (short)((wxyz & 0x00003F00) >> 8);
short z = (short)((wxyz & 0x000000FC) >> 2);
These are correct values.
User contributions licensed under CC BY-SA 3.0