Hi All,
Is there any difference?andCode:unsigned char data; unsigned int worddata; data = (unsigned char)worddata;Code:data = (unsigned char)(0x00FF & worddata);
Hi All,
Is there any difference?andCode:unsigned char data; unsigned int worddata; data = (unsigned char)worddata;Code:data = (unsigned char)(0x00FF & worddata);
I'm guessing it's the wrong way around (because that makes no sense). Perhaps it should be:Code:data = (unsigned char)(0x00FF & worddata);
And if that is the case, then yes, they are different.Code:data = (unsigned char)(worddata & 0x00FF);
Careful here, because
Is the same asCode:(unsigned char)worddata
While the second example uses a different mask (gets the second byte instead of the first).Code:worddata & 0xFF
Results may vary on different endian systems, but the two lines of code are clearly different.
0xFF & x and x & 0xFF are exactly the same thing.
The truth table for AND is symmetrical, so 1 & 0 or 0 & 1 will both result in 0, 1 & 1 will result in 1, 0 & 0 results in 0.
A cast to unsigned char, assuming char is 8 bits, should be implemented by the compiler as something equivalent to x & 0xff.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
I'd just use a cast myself. The char can not hold more than 0xff anyways, so some way or another, the compiler will have to do the necessary operations to chop it down. Of course, it may be more obvious what you want to do if you also and with 0xFF - but the risk is that the compiler doesn't understand what's going on, and adds the extra and into the code [it is, after all what you asked for, even if it's pointless].
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
And another one.is it always true that bits on the left hand side are '0' ? And in this case final value is 0x00E9? What if I want 3th byte from long (4B)?Code:WORD data; data = 0xE9E9; data >>= 8;orCode:LONG Data = 0x12345678; BYTE byte; byte = (BYTE)(Data >> 16);Which is better (safer, faster etc.)?Code:byte = (BYTE)((Data & 0x00FF0000) >> 16);
The best thing to do is to explicitly specify what data you want to keep. You can do this by shifting.
For example:
By shifting the data into the correct place, it is then safe to truncate the data because you've just made sure that the data you want to keep is placed in the first byte.Code:unsigned short data = 0xFF00; unsigned char data2 = (char)(data >> 8);
Endianness is a tricky beast, so this may or may not work. Something better would probably be:
Because by shifting the data into the right "place", it is now merely 16 bits, which can be represented inside a short.Code:unsigned int data3 = 0xFFFF0000; unsigned short data4 = (data3 >> 16);
But the general rule is: don't truncate data unless necessary. Keep the chain, keep the size.
For an unsigned value, yes. For a signed value, the sign should fill the upper bits (and in this case, that would mean 1's, since the top bit of the original value is set).
Assuming that BYTE is indeed a byte (such as unsigned char on a "normal" machine), there is no need to use and here, a cast is sufficient. It also makes no difference if you use and first, or last (after the shift) from a logical perspective, but an and with 0xFF is potentially shorter than the and with a 32-bit number (0x00FF0000), so anding last [assuming we store the result in, say, a 32-bit integer, so we need the AND to make sure we get rid of un-needed bits].What if I want 3th byte from long (4B)?orCode:LONG Data = 0x12345678; BYTE byte; byte = (BYTE)(Data >> 16);Which is better (safer, faster etc.)?Code:byte = (BYTE)((Data & 0x00FF0000) >> 16);
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.