Bitwise Operations Q
vegastech
Posts: 369
Pardon my ignorance here, but...
How do I get the least significant bit by BANDing with $FF? I wrote it out longhand, and when I BAND $FF and $FC, I get $FC. Since FC is greater than a byte (equal to 252) and I need to stay under a byte, do I get rid of the $F with something like an LShift?
How do I get the least significant bit by BANDing with $FF? I wrote it out longhand, and when I BAND $FF and $FC, I get $FC. Since FC is greater than a byte (equal to 252) and I need to stay under a byte, do I get rid of the $F with something like an LShift?
0
Comments
That's not what big/little endian means. Endianness almost always refers to byte order, not bit order. If you have a two-byte quantity 0x0142 (decimal 322) it can be sent over the wire as $01,$42 (big endian, or most significant byte first) or $42,$01 (little endian, or least significant byte first). The bit order is always the same. Intel processors are little endian because they store the least significant byte of a word in the lowest memory address (or "first"). http://en.wikipedia.org/wiki/Endianness
You can still have bit endianness. Given by time anything reaches NetLinx's level of abstraction is should be big endian (MSB 0).
Back to the original question though. It sounds as though you may be getting confused with a hex representation of byte. A value like $FC is not two bytes (F and C), it is instead a representation of a single value comprised of 0xF (15 in base 10) times 16^1 for your highest 4 bits and 0xC (12 in base 10) times 16^0, which gives you bits 3 through 0. In order to get the least significant byte of a value that is in NetLinx land you're already doing the right thing by band'ing with $FF.
It helps to try and visualise what is actually going on. All endianness guff aside, lets just say you've got the value 0x12C:
BAND'ing basically says 'tell me what bits are high for values on both sides of the BAND operator'.
In order to get the least significant byte BAND'ing the value with 0xFF means that anything above bit 7 (where $FF finishes) is truncated and you are just getting the value from bits 7 through 0.
So when you band:
You get:
LSHIFTing (<<) and RSHIFTing (>>) allows you to shift bits left or right by how ever many places you specifiy on the right hand side of the operator. By themselves they're probably not what you're after for getting the LSB, however they're usefull operation for creating masks to use in BAND, BOR etc operations.
You question about dropping anything above 100 is a completely seperate issue to anything to do with these bitwise operations. To do that you'll most likely be wanting the mod (%) operator. This will give the remainder of a value divided by another. So in the case of getting components of a number in base 10 under 100 you could use somethine like number % 100. There's plenty of info on it in the help files.
You will never get a higher value than that which you use to BAND against. FF (or 255) means that all eight bits (valued as 1,2,4,8,16,32,64,128) are high or active or set or whatever. BAND compares the individual bits of this value with another and returns the bit values of all bits that are high in the both values of the comparison.
11111111 BAND
11111111 =
11111111
10101010 BAND
11111111 =
10101010
(something higher than FF)
11111111011 BAND
00011111111=
00011111011
The last example shows getting the lower eight bits as often used in checksum calculations.
Hope this helps.
Thanks to TurnipTruck, Phreak, and True for helping to explain this rather difficult topic (at least for me!). I wasn't putting together the fact that $157 was in fact a 16 bit integer, and not an 8 bit. Rookie misconception (or misremembering), I suppose. Now that I can actually visualize (and more importantly draw them on a sheet of paper *wink*) bit values (or bytes, etc) above FF, I think I will have an easier time. Thanks again for everyone's .02 cents!
For more info checkout tech notes 210, 457 and 518.
Kenny