Bitwise Operation Help
The response is !6 HTS 01 01 03 $1A (the spaces were added to seperate the chunks of data)
I am fine seperating out the first chunk [01] = HD or Not HD
I am fine with the second chunk [01] = current HD stream
Its the third that I need help with [03] = available HD streams. There are 8 possible streams and 03 is a hex representation of an 8-bit binary number where each bit is 1 or 0 representing the available streams.
In the example it is [03] = 11000000 which equates to Streams 1 and 2 are available, but 3-8 are not.
I want to then turn on feedback on the touch screen for the streams that are available and put the available streams into an array so I can toggle through the available streams.
Thanks for any help you can give.
Comments
-
In the example it is [03] = 11000000 which equates to Streams 1 and 2 are available, but 3-8 are not.
I want to then turn on feedback on the touch screen for the streams that are available and put the available streams into an array so I can toggle through the available streams.
Thanks for any help you can give.
$03 should read 00000011.
if sMyChar = $03 (or whatever hex code you get)
one way would be to individually check each channel for a one or zero
sMyChar BAND $01 (00000001) will return an $01 if there is a stream present and $00 if there's none
sMyChar BAND $02 (00000010) will return an $02 if there is a stream present and $00 if there's none
sMyChar BAND $04 (00000100) will return an $04 if there is a stream present and $00 if there's none
same for $08 (00001000)
same for $10 (00010000)
and so on.
There may be a better way, that's the first one that came to mind. -
I think you got it backwards. 00000011 = 3. But as I understand it, the problem is to isolate which bits are on and which are off. There's a pretty good guide that I got on an AMX.com Tech Note called Bitwise Operations. But I'll summarize how you'd do this anyway.
First write a function that gets passed an integer n and finds 2^n. This is a pretty easy task, you could even do it recursively if you want.
Then go through a loop for(i=0;i<8;i++). This will run the loop 8 times, one for each bit.
If ( 2^i & Chunk3 ) then you know stream (i+1) is available. How? Because you compared the bits of the two numbers using the bitwise AND (&).
00000011 = 3
00000001 = 1 = 2^0
00000001 = 3&1 ... Stream 1 is available
00000011 = 3
00000010 = 2 = 2^1
00000010 = 3&2 ... Stream 2 is available.
00000011 = 3
00000100 = 4 = 2^2
00000000 = 3&4 .... Stream 3 is not available. (because the two numbers had no bits in common)
and so on. -
That'd work for me . . . I'd just throw it in a loop and fix it to an array.TonyAngelo wrote: »$03 should read 00000011.
if sMyChar = $03 (or whatever hex code you get)
one way would be to individually check each channel for a one or zero
sMyChar BAND $01 (00000001) will return an $01 if there is a stream present and $00 if there's none
sMyChar BAND $02 (00000010) will return an $02 if there is a stream present and $00 if there's none
sMyChar BAND $04 (00000100) will return an $04 if there is a stream present and $00 if there's none
same for $08 (00001000)
same for $10 (00010000)
and so on.
There may be a better way, that's the first one that came to mind.
And thanks, I never liked working with binary, and thus far have been able to stay away from it. Now, even I might not be afraid to tackle it!
-
I'd skin the cat this way:
define_function integer fn_bits_of_hex(integer i_hex) { stack_var integer i, iBits[8] for(i = 1; i <= 8; i++) { iBits[i] = i_hex BAND $01 i_hex = type_cast (i_hex >> 1) } //do something with iBits! } -
Now, even I might not be afraid to tackle it!

Are you trying to imply that if I can figure it out it must not be too hard?
If you're scared of binary then pray you never have to parse feedback from a Krell. -
Oh I needed a good laugh! Thanks!TonyAngelo wrote: »Are you trying to imply that if I can figure it out it must not be too hard?
If you're scared of binary then pray you never have to parse feedback from a Krell.
Well, the only time I might encounter a Krell is if I'm doing a job for someone else. But thanks for the heads up, I'll be sure that we don't sell any!
-
One more way:
Here is a one line function that given a number and a bit position will return the value of the bit. The least most significant bit is bit 0.DEFINE_FUNCTION CHAR fnIsBitSet (integer number, char bit) { RETURN number & (1<<bit) = 1<<bit } -
Joe Hebert wrote: »One more way:
Here is a one line function that given a number and a bit position will return the value of the bit. The least most significant bit is bit 0.DEFINE_FUNCTION CHAR fnIsBitSet (integer number, char bit) { RETURN number & (1<<bit) = 1<<bit }
You will have to explain that one Joe, as I don't follow but would like to understand. Why is the bit argument a char?
Not sure what you mean by "least most significant bit". Is that a typo?
Thanks,
Paul -
Joe Hebert wrote: »RETURN number & (1<<bit) = 1<<bit
This is the bit that I don't get. -
Haha! No pun intended?TonyAngelo wrote: »This is the bit that I don't get.
-
Joe's coding is the correct way to do this function. However this may help to explain it better....
// number value: 0- 65535 // // bit value: 0 - 7 //7654 3210 //xxxx xxxx DEFINE_FUNCTION CHAR isBitSet (integer number, char bit) { STACK_VAR CHAR cBitValue; // make the bit value, // Bit 7 = $80 MSB // Bit 6 = $40 // Bit 5 = $20 // Bit 4 = $10 // Bit 3 = $08 // Bit 2 = $04 // Bit 1 = $02 // Bit 0 = $01 LSB cBitValue = 1 << bit; IF ((number & cBitValue) == cBitValue) RETURN TRUE; ELSE RETURN FALSE; } -
Got it.
Thanks for all the quick replies. -
You will have to explain that one Joe, as I don't follow but would like to understand. Why is the bit argument a char?
Not sure what you mean by "least most significant bit". Is that a typo?
Thanks,
Paul
char is a 8-bit numeric datatype, which is smaller than the 16-bit integer. It can represent values 0-255, which is enough to tell which bit you want out of a 16-bit integer. Also called a byte, short, or uint8 in other programming languages.
Typo, he meant least significant bit.
Also, you can simplify the test to "number & (1<<bit) != 0" since it doesn't matter what value it has as long as it isn't zero.
<< is the left-shift operator. 1<<0 = $01 (b00000001). 1<<1 = $02 (b00000010). 1<<7 = $80 (b10000000) The expression (1<<bit) lets you easily mask out the single bit you're interested in. -
char is a 8-bit numeric datatype, which is smaller than the 16-bit integer. It can represent values 0-255, which is enough to tell which bit you want out of a 16-bit integer. Also called a byte, short, or uint8 in other programming languages.
Typo, he meant least significant bit.
Also, you can simplify the test to "number & (1<<bit) != 0" since it doesn't matter what value it has as long as it isn't zero.
<< is the left-shift operator. 1<<0 = $01 (b00000001). 1<<1 = $02 (b00000010). 1<<7 = $80 (b10000000) The expression (1<<bit) lets you easily mask out the single bit you're interested in.
Thanks for the explanation. It looked a little odd to me for a couple of reasons, one of which you mentioned (!= 0). The other is that the precedence of & is weaker than != so number will be anded with the result of (1<<bit) != 0 (which will always be 1) rather than having (number & (1<<bit)) compared against 0. Is this not the case? It is in C++ but I don't have a master to test against.
It may need mentioning to anyone using this function that the value of 'bit' starts at 0 not 1, as in the zeroth bit. So for it to return true for the number 1, bit would have to have a value of 0. I would use an int rather than a char for the argument just for clarity.
Paul -
I didn?t realize one short line of code could swell to such controversy.

Correct. I mentioned that in my original post and AMXJeff reiterated it. Starting with 0 instead of 1 is the mathematically correct way to do it.a_riot42 wrote:It may need mentioning to anyone using this function that the value of 'bit' starts at 0 not 1
It?s not returning true or false for a number. The function returns the value of a bit of the number passed in. If you pass in any odd number with bit 0 then the function will always return 1 (TRUE) since b0 is always set for an odd number.a_riot42 wrote:So for it to return true for the number 1, bit would have to have a value of 0.
Curious as to why you feel increasing the memory space of the bit parameter to an INT adds clarity. The only ?legal? values for bit are 0-15 since the integer number passed in is 16 bits wide. But as with many things in the programming world, to each their own. An INT will work just as well as a CHAR. You can also use an INT for the RETURN instead of a CHAR. The data types of the function best suited my needs at at the time.a_riot42 wrote:I would use an int rather than a char for the argument just for clarity.
Yes, that?s not the case. If you test it, you will find the function works exactly as expected and intended.a_riot42 wrote:It looked a little odd to me for a couple of reasons, one of which you mentioned (!= 0).The other is that the precedence of & is weaker than != so number will be anded with the result of (1<<bit) != 0 (which will always be 1) rather than having (number & (1<<bit)) compared against 0. Is this not the case?
You?re a very punny guy. (Where did I hear that before?)TonyAngelo wrote:This is the bit that I don't get.
-
Joe Hebert wrote: »Yes, that?s not the case. If you test it, you will find the function works exactly as expected and intended.
That puzzles me. I tested it with a C++ compiler and it doesn't work correctly without the added parentheses and the operator precedence in Netlinx is the same as C++. I don't have a master to try it out on though to confirm until Monday.
Using 9 as the number and 1 as the bit with this code:bool isBitSet (int number, int bit) { return number & (1<<bit) == 1<<bit; }
The result is 1 which is wrong. However, it is right if (1<<bit) == 1<<bit gets evaluated first since that would be 1, and then 9 anded with 1 is of course 1.
Using 9 as the number and 1 as the bit with this codebool isBitSet (int number, int bit) { return (number & (1<<bit)) == 1<<bit; }
The result is 0 which is correct, since (number & (1<<bit)) gets evaluated first which is 0, and then 0 compared with 1 will return 0.
I don't understand why it would work with Netlinx code and not C when the operator precedence is the same but I will figure it out Monday I guess.Joe Hebert wrote: »Curious as to why you feel increasing the memory space of the bit parameter to an INT adds clarity. The only ?legal? values for bit are 0-15 since the integer number passed in is 16 bits wide. But as with many things in the programming world, to each their own. An INT will work just as well as a CHAR. You can also use an INT for the RETURN instead of a CHAR. The data types of the function best suited my needs at at the time.
Yes it is just a quirk of mine to use an int if you are returning an int value (1 or 0 as you mentioned) and to use a char if you are returning an ascii character. Obviously you can interchange them, but I will generally always sacrifice memory (especially if its only one byte like in this case) for clarity. For instance I will never write:char num = 2 char num2 = 3 char num3 = num + num2
even though it saves me three bytes as opposed to:int num = 2 int num2 = 3 int num3 = num + num2
Paul -
I?ll give you a head start. The following code:a_riot42 wrote:I don't have a master to try it out on though to confirm until Monday.DEFINE_DEVICE dvTP = 10001:1:0 DEFINE_VARIABLE DEFINE_FUNCTION INTEGER fnIsBitSet (integer number, integer bit) { RETURN number & (1<<bit) == 1<<bit } DEFINE_EVENT BUTTON_EVENT[dvTP,1] { PUSH: { INTEGER number INTEGER bit FOR (number=0; number<16; number++) { SEND_STRING 0,"'Testing number ',ITOA(number),FORMAT(' ($%02X) ',number),'bits 0-15'" FOR (bit=0; bit<16; bit++) { SEND_STRING 0, "ITOA(number),FORMAT(' ($%02X) ',number),' bit ',ITOA(bit),' = ',ITOA(fnIsBitSet(number,bit))" } SEND_STRING 0,"'---'" } } }
?produces the following output when button 1 is pushed:Line 1 :: Testing number 0 ($00) bits 0-15 - 18:33:15 Line 2 :: 0 ($00) bit 0 = 0 - 18:33:15 Line 3 :: 0 ($00) bit 1 = 0 - 18:33:15 Line 4 :: 0 ($00) bit 2 = 0 - 18:33:15 Line 5 :: 0 ($00) bit 3 = 0 - 18:33:15 Line 6 :: 0 ($00) bit 4 = 0 - 18:33:15 Line 7 :: 0 ($00) bit 5 = 0 - 18:33:15 Line 8 :: 0 ($00) bit 6 = 0 - 18:33:15 Line 9 :: 0 ($00) bit 7 = 0 - 18:33:15 Line 10 :: 0 ($00) bit 8 = 0 - 18:33:15 Line 11 :: 0 ($00) bit 9 = 0 - 18:33:15 Line 12 :: 0 ($00) bit 10 = 0 - 18:33:15 Line 13 :: 0 ($00) bit 11 = 0 - 18:33:15 Line 14 :: 0 ($00) bit 12 = 0 - 18:33:15 Line 15 :: 0 ($00) bit 13 = 0 - 18:33:15 Line 16 :: 0 ($00) bit 14 = 0 - 18:33:15 Line 17 :: 0 ($00) bit 15 = 0 - 18:33:15 Line 18 :: --- - 18:33:15 Line 19 :: Testing number 1 ($01) bits 0-15 - 18:33:15 Line 20 :: 1 ($01) bit 0 = 1 - 18:33:15 Line 21 :: 1 ($01) bit 1 = 0 - 18:33:15 Line 22 :: 1 ($01) bit 2 = 0 - 18:33:15 Line 23 :: 1 ($01) bit 3 = 0 - 18:33:15 Line 24 :: 1 ($01) bit 4 = 0 - 18:33:15 Line 25 :: 1 ($01) bit 5 = 0 - 18:33:15 Line 26 :: 1 ($01) bit 6 = 0 - 18:33:15 Line 27 :: 1 ($01) bit 7 = 0 - 18:33:15 Line 28 :: 1 ($01) bit 8 = 0 - 18:33:15 Line 29 :: 1 ($01) bit 9 = 0 - 18:33:15 Line 30 :: 1 ($01) bit 10 = 0 - 18:33:15 Line 31 :: 1 ($01) bit 11 = 0 - 18:33:15 Line 32 :: 1 ($01) bit 12 = 0 - 18:33:15 Line 33 :: 1 ($01) bit 13 = 0 - 18:33:15 Line 34 :: 1 ($01) bit 14 = 0 - 18:33:15 Line 35 :: 1 ($01) bit 15 = 0 - 18:33:15 Line 36 :: --- - 18:33:15 Line 37 :: Testing number 2 ($02) bits 0-15 - 18:33:15 Line 38 :: 2 ($02) bit 0 = 0 - 18:33:15 Line 39 :: 2 ($02) bit 1 = 1 - 18:33:15 Line 40 :: 2 ($02) bit 2 = 0 - 18:33:15 Line 41 :: 2 ($02) bit 3 = 0 - 18:33:15 Line 42 :: 2 ($02) bit 4 = 0 - 18:33:15 Line 43 :: 2 ($02) bit 5 = 0 - 18:33:15 Line 44 :: 2 ($02) bit 6 = 0 - 18:33:15 Line 45 :: 2 ($02) bit 7 = 0 - 18:33:15 Line 46 :: 2 ($02) bit 8 = 0 - 18:33:15 Line 47 :: 2 ($02) bit 9 = 0 - 18:33:15 Line 48 :: 2 ($02) bit 10 = 0 - 18:33:15 Line 49 :: 2 ($02) bit 11 = 0 - 18:33:15 Line 50 :: 2 ($02) bit 12 = 0 - 18:33:15 Line 51 :: 2 ($02) bit 13 = 0 - 18:33:15 Line 52 :: 2 ($02) bit 14 = 0 - 18:33:15 Line 53 :: 2 ($02) bit 15 = 0 - 18:33:15 Line 54 :: --- - 18:33:15 Line 55 :: Testing number 3 ($03) bits 0-15 - 18:33:15 Line 56 :: 3 ($03) bit 0 = 1 - 18:33:15 Line 57 :: 3 ($03) bit 1 = 1 - 18:33:15 Line 58 :: 3 ($03) bit 2 = 0 - 18:33:15 Line 59 :: 3 ($03) bit 3 = 0 - 18:33:15 Line 60 :: 3 ($03) bit 4 = 0 - 18:33:15 Line 61 :: 3 ($03) bit 5 = 0 - 18:33:15 Line 62 :: 3 ($03) bit 6 = 0 - 18:33:15 Line 63 :: 3 ($03) bit 7 = 0 - 18:33:15 Line 64 :: 3 ($03) bit 8 = 0 - 18:33:15 Line 65 :: 3 ($03) bit 9 = 0 - 18:33:15 Line 66 :: 3 ($03) bit 10 = 0 - 18:33:15 Line 67 :: 3 ($03) bit 11 = 0 - 18:33:15 Line 68 :: 3 ($03) bit 12 = 0 - 18:33:15 Line 69 :: 3 ($03) bit 13 = 0 - 18:33:15 Line 70 :: 3 ($03) bit 14 = 0 - 18:33:15 Line 71 :: 3 ($03) bit 15 = 0 - 18:33:15 Line 72 :: --- - 18:33:15 Line 73 :: Testing number 4 ($04) bits 0-15 - 18:33:15 Line 74 :: 4 ($04) bit 0 = 0 - 18:33:15 Line 75 :: 4 ($04) bit 1 = 0 - 18:33:15 Line 76 :: 4 ($04) bit 2 = 1 - 18:33:15 Line 77 :: 4 ($04) bit 3 = 0 - 18:33:15 Line 78 :: 4 ($04) bit 4 = 0 - 18:33:15 Line 79 :: 4 ($04) bit 5 = 0 - 18:33:15 Line 80 :: 4 ($04) bit 6 = 0 - 18:33:15 Line 81 :: 4 ($04) bit 7 = 0 - 18:33:15 Line 82 :: 4 ($04) bit 8 = 0 - 18:33:15 Line 83 :: 4 ($04) bit 9 = 0 - 18:33:15 Line 84 :: 4 ($04) bit 10 = 0 - 18:33:15 Line 85 :: 4 ($04) bit 11 = 0 - 18:33:15 Line 86 :: 4 ($04) bit 12 = 0 - 18:33:15 Line 87 :: 4 ($04) bit 13 = 0 - 18:33:15 Line 88 :: 4 ($04) bit 14 = 0 - 18:33:15 Line 89 :: 4 ($04) bit 15 = 0 - 18:33:15 Line 90 :: --- - 18:33:15 Line 91 :: Testing number 5 ($05) bits 0-15 - 18:33:15 Line 92 :: 5 ($05) bit 0 = 1 - 18:33:15 Line 93 :: 5 ($05) bit 1 = 0 - 18:33:15 Line 94 :: 5 ($05) bit 2 = 1 - 18:33:15 Line 95 :: 5 ($05) bit 3 = 0 - 18:33:15 Line 96 :: 5 ($05) bit 4 = 0 - 18:33:15 Line 97 :: 5 ($05) bit 5 = 0 - 18:33:15 Line 98 :: 5 ($05) bit 6 = 0 - 18:33:15 Line 99 :: 5 ($05) bit 7 = 0 - 18:33:15 Line 100 :: 5 ($05) bit 8 = 0 - 18:33:15 Line 101 :: 5 ($05) bit 9 = 0 - 18:33:15 Line 102 :: 5 ($05) bit 10 = 0 - 18:33:15 Line 103 :: 5 ($05) bit 11 = 0 - 18:33:15 Line 104 :: 5 ($05) bit 12 = 0 - 18:33:15 Line 105 :: 5 ($05) bit 13 = 0 - 18:33:15 Line 106 :: 5 ($05) bit 14 = 0 - 18:33:15 Line 107 :: 5 ($05) bit 15 = 0 - 18:33:15 Line 108 :: --- - 18:33:15 Line 109 :: Testing number 6 ($06) bits 0-15 - 18:33:15 Line 110 :: 6 ($06) bit 0 = 0 - 18:33:15 Line 111 :: 6 ($06) bit 1 = 1 - 18:33:15 Line 112 :: 6 ($06) bit 2 = 1 - 18:33:15 Line 113 :: 6 ($06) bit 3 = 0 - 18:33:15 Line 114 :: 6 ($06) bit 4 = 0 - 18:33:15 Line 115 :: 6 ($06) bit 5 = 0 - 18:33:15 Line 116 :: 6 ($06) bit 6 = 0 - 18:33:15 Line 117 :: 6 ($06) bit 7 = 0 - 18:33:15 Line 118 :: 6 ($06) bit 8 = 0 - 18:33:15 Line 119 :: 6 ($06) bit 9 = 0 - 18:33:15 Line 120 :: 6 ($06) bit 10 = 0 - 18:33:15 Line 121 :: 6 ($06) bit 11 = 0 - 18:33:15 Line 122 :: 6 ($06) bit 12 = 0 - 18:33:15 Line 123 :: 6 ($06) bit 13 = 0 - 18:33:15 Line 124 :: 6 ($06) bit 14 = 0 - 18:33:15 Line 125 :: 6 ($06) bit 15 = 0 - 18:33:15 Line 126 :: --- - 18:33:15 Line 127 :: Testing number 7 ($07) bits 0-15 - 18:33:15 Line 128 :: 7 ($07) bit 0 = 1 - 18:33:15 Line 129 :: 7 ($07) bit 1 = 1 - 18:33:15 Line 130 :: 7 ($07) bit 2 = 1 - 18:33:15 Line 131 :: 7 ($07) bit 3 = 0 - 18:33:15 Line 132 :: 7 ($07) bit 4 = 0 - 18:33:15 Line 133 :: 7 ($07) bit 5 = 0 - 18:33:15 Line 134 :: 7 ($07) bit 6 = 0 - 18:33:15 Line 135 :: 7 ($07) bit 7 = 0 - 18:33:15 Line 136 :: 7 ($07) bit 8 = 0 - 18:33:15 Line 137 :: 7 ($07) bit 9 = 0 - 18:33:15 Line 138 :: 7 ($07) bit 10 = 0 - 18:33:15 Line 139 :: 7 ($07) bit 11 = 0 - 18:33:15 Line 140 :: 7 ($07) bit 12 = 0 - 18:33:15 Line 141 :: 7 ($07) bit 13 = 0 - 18:33:15 Line 142 :: 7 ($07) bit 14 = 0 - 18:33:15 Line 143 :: 7 ($07) bit 15 = 0 - 18:33:15 Line 144 :: --- - 18:33:15 Line 145 :: Testing number 8 ($08) bits 0-15 - 18:33:15 Line 146 :: 8 ($08) bit 0 = 0 - 18:33:15 Line 147 :: 8 ($08) bit 1 = 0 - 18:33:15 Line 148 :: 8 ($08) bit 2 = 0 - 18:33:15 Line 149 :: 8 ($08) bit 3 = 1 - 18:33:15 Line 150 :: 8 ($08) bit 4 = 0 - 18:33:15 Line 151 :: 8 ($08) bit 5 = 0 - 18:33:15 Line 152 :: 8 ($08) bit 6 = 0 - 18:33:15 Line 153 :: 8 ($08) bit 7 = 0 - 18:33:15 Line 154 :: 8 ($08) bit 8 = 0 - 18:33:15 Line 155 :: 8 ($08) bit 9 = 0 - 18:33:15 Line 156 :: 8 ($08) bit 10 = 0 - 18:33:15 Line 157 :: 8 ($08) bit 11 = 0 - 18:33:15 Line 158 :: 8 ($08) bit 12 = 0 - 18:33:15 Line 159 :: 8 ($08) bit 13 = 0 - 18:33:15 Line 160 :: 8 ($08) bit 14 = 0 - 18:33:15 Line 161 :: 8 ($08) bit 15 = 0 - 18:33:15 Line 162 :: --- - 18:33:15 Line 163 :: Testing number 9 ($09) bits 0-15 - 18:33:15 Line 164 :: 9 ($09) bit 0 = 1 - 18:33:15 Line 165 :: 9 ($09) bit 1 = 0 - 18:33:15 Line 166 :: 9 ($09) bit 2 = 0 - 18:33:15 Line 167 :: 9 ($09) bit 3 = 1 - 18:33:15 Line 168 :: 9 ($09) bit 4 = 0 - 18:33:15 Line 169 :: 9 ($09) bit 5 = 0 - 18:33:15 Line 170 :: 9 ($09) bit 6 = 0 - 18:33:15 Line 171 :: 9 ($09) bit 7 = 0 - 18:33:15 Line 172 :: 9 ($09) bit 8 = 0 - 18:33:15 Line 173 :: 9 ($09) bit 9 = 0 - 18:33:15 Line 174 :: 9 ($09) bit 10 = 0 - 18:33:15 Line 175 :: 9 ($09) bit 11 = 0 - 18:33:15 Line 176 :: 9 ($09) bit 12 = 0 - 18:33:15 Line 177 :: 9 ($09) bit 13 = 0 - 18:33:15 Line 178 :: 9 ($09) bit 14 = 0 - 18:33:15 Line 179 :: 9 ($09) bit 15 = 0 - 18:33:15 Line 180 :: --- - 18:33:15 Line 181 :: Testing number 10 ($0A) bits 0-15 - 18:33:15 Line 182 :: 10 ($0A) bit 0 = 0 - 18:33:15 Line 183 :: 10 ($0A) bit 1 = 1 - 18:33:15 Line 184 :: 10 ($0A) bit 2 = 0 - 18:33:15 Line 185 :: 10 ($0A) bit 3 = 1 - 18:33:15 Line 186 :: 10 ($0A) bit 4 = 0 - 18:33:15 Line 187 :: 10 ($0A) bit 5 = 0 - 18:33:15 Line 188 :: 10 ($0A) bit 6 = 0 - 18:33:15 Line 189 :: 10 ($0A) bit 7 = 0 - 18:33:15 Line 190 :: 10 ($0A) bit 8 = 0 - 18:33:15 Line 191 :: 10 ($0A) bit 9 = 0 - 18:33:15 Line 192 :: 10 ($0A) bit 10 = 0 - 18:33:15 Line 193 :: 10 ($0A) bit 11 = 0 - 18:33:15 Line 194 :: 10 ($0A) bit 12 = 0 - 18:33:15 Line 195 :: 10 ($0A) bit 13 = 0 - 18:33:15 Line 196 :: 10 ($0A) bit 14 = 0 - 18:33:15 Line 197 :: 10 ($0A) bit 15 = 0 - 18:33:15 Line 198 :: --- - 18:33:15 Line 199 :: Testing number 11 ($0B) bits 0-15 - 18:33:15 Line 200 :: 11 ($0B) bit 0 = 1 - 18:33:15 Line 201 :: 11 ($0B) bit 1 = 1 - 18:33:15 Line 202 :: 11 ($0B) bit 2 = 0 - 18:33:15 Line 203 :: 11 ($0B) bit 3 = 1 - 18:33:15 Line 204 :: 11 ($0B) bit 4 = 0 - 18:33:15 Line 205 :: 11 ($0B) bit 5 = 0 - 18:33:15 Line 206 :: 11 ($0B) bit 6 = 0 - 18:33:15 Line 207 :: 11 ($0B) bit 7 = 0 - 18:33:15 Line 208 :: 11 ($0B) bit 8 = 0 - 18:33:15 Line 209 :: 11 ($0B) bit 9 = 0 - 18:33:15 Line 210 :: 11 ($0B) bit 10 = 0 - 18:33:15 Line 211 :: 11 ($0B) bit 11 = 0 - 18:33:15 Line 212 :: 11 ($0B) bit 12 = 0 - 18:33:15 Line 213 :: 11 ($0B) bit 13 = 0 - 18:33:15 Line 214 :: 11 ($0B) bit 14 = 0 - 18:33:15 Line 215 :: 11 ($0B) bit 15 = 0 - 18:33:15 Line 216 :: --- - 18:33:15 Line 217 :: Testing number 12 ($0C) bits 0-15 - 18:33:15 Line 218 :: 12 ($0C) bit 0 = 0 - 18:33:15 Line 219 :: 12 ($0C) bit 1 = 0 - 18:33:15 Line 220 :: 12 ($0C) bit 2 = 1 - 18:33:15 Line 221 :: 12 ($0C) bit 3 = 1 - 18:33:15 Line 222 :: 12 ($0C) bit 4 = 0 - 18:33:15 Line 223 :: 12 ($0C) bit 5 = 0 - 18:33:15 Line 224 :: 12 ($0C) bit 6 = 0 - 18:33:15 Line 225 :: 12 ($0C) bit 7 = 0 - 18:33:15 Line 226 :: 12 ($0C) bit 8 = 0 - 18:33:15 Line 227 :: 12 ($0C) bit 9 = 0 - 18:33:15 Line 228 :: 12 ($0C) bit 10 = 0 - 18:33:15 Line 229 :: 12 ($0C) bit 11 = 0 - 18:33:15 Line 230 :: 12 ($0C) bit 12 = 0 - 18:33:15 Line 231 :: 12 ($0C) bit 13 = 0 - 18:33:15 Line 232 :: 12 ($0C) bit 14 = 0 - 18:33:15 Line 233 :: 12 ($0C) bit 15 = 0 - 18:33:15 Line 234 :: --- - 18:33:15 Line 235 :: Testing number 13 ($0D) bits 0-15 - 18:33:15 Line 236 :: 13 ($0D) bit 0 = 1 - 18:33:15 Line 237 :: 13 ($0D) bit 1 = 0 - 18:33:15 Line 238 :: 13 ($0D) bit 2 = 1 - 18:33:15 Line 239 :: 13 ($0D) bit 3 = 1 - 18:33:15 Line 240 :: 13 ($0D) bit 4 = 0 - 18:33:15 Line 241 :: 13 ($0D) bit 5 = 0 - 18:33:15 Line 242 :: 13 ($0D) bit 6 = 0 - 18:33:15 Line 243 :: 13 ($0D) bit 7 = 0 - 18:33:15 Line 244 :: 13 ($0D) bit 8 = 0 - 18:33:15 Line 245 :: 13 ($0D) bit 9 = 0 - 18:33:15 Line 246 :: 13 ($0D) bit 10 = 0 - 18:33:15 Line 247 :: 13 ($0D) bit 11 = 0 - 18:33:15 Line 248 :: 13 ($0D) bit 12 = 0 - 18:33:15 Line 249 :: 13 ($0D) bit 13 = 0 - 18:33:15 Line 250 :: 13 ($0D) bit 14 = 0 - 18:33:15 Line 251 :: 13 ($0D) bit 15 = 0 - 18:33:15 Line 252 :: --- - 18:33:15 Line 253 :: Testing number 14 ($0E) bits 0-15 - 18:33:15 Line 254 :: 14 ($0E) bit 0 = 0 - 18:33:15 Line 255 :: 14 ($0E) bit 1 = 1 - 18:33:15 Line 256 :: 14 ($0E) bit 2 = 1 - 18:33:15 Line 257 :: 14 ($0E) bit 3 = 1 - 18:33:15 Line 258 :: 14 ($0E) bit 4 = 0 - 18:33:15 Line 259 :: 14 ($0E) bit 5 = 0 - 18:33:15 Line 260 :: 14 ($0E) bit 6 = 0 - 18:33:15 Line 261 :: 14 ($0E) bit 7 = 0 - 18:33:15 Line 262 :: 14 ($0E) bit 8 = 0 - 18:33:15 Line 263 :: 14 ($0E) bit 9 = 0 - 18:33:15 Line 264 :: 14 ($0E) bit 10 = 0 - 18:33:15 Line 265 :: 14 ($0E) bit 11 = 0 - 18:33:15 Line 266 :: 14 ($0E) bit 12 = 0 - 18:33:15 Line 267 :: 14 ($0E) bit 13 = 0 - 18:33:15 Line 268 :: 14 ($0E) bit 14 = 0 - 18:33:15 Line 269 :: 14 ($0E) bit 15 = 0 - 18:33:15 Line 270 :: --- - 18:33:15 Line 271 :: Testing number 15 ($0F) bits 0-15 - 18:33:15 Line 272 :: 15 ($0F) bit 0 = 1 - 18:33:15 Line 273 :: 15 ($0F) bit 1 = 1 - 18:33:15 Line 274 :: 15 ($0F) bit 2 = 1 - 18:33:15 Line 275 :: 15 ($0F) bit 3 = 1 - 18:33:15 Line 276 :: 15 ($0F) bit 4 = 0 - 18:33:15 Line 277 :: 15 ($0F) bit 5 = 0 - 18:33:15 Line 278 :: 15 ($0F) bit 6 = 0 - 18:33:15 Line 279 :: 15 ($0F) bit 7 = 0 - 18:33:15 Line 280 :: 15 ($0F) bit 8 = 0 - 18:33:15 Line 281 :: 15 ($0F) bit 9 = 0 - 18:33:15 Line 282 :: 15 ($0F) bit 10 = 0 - 18:33:15 Line 283 :: 15 ($0F) bit 11 = 0 - 18:33:15 Line 284 :: 15 ($0F) bit 12 = 0 - 18:33:15 Line 285 :: 15 ($0F) bit 13 = 0 - 18:33:15 Line 286 :: 15 ($0F) bit 14 = 0 - 18:33:15 Line 287 :: 15 ($0F) bit 15 = 0 - 18:33:15 Line 288 :: --- - 18:33:15
-
Interesting. Thanks for running the test. The = was changed to == though. I wonder if that made a difference. Can you run the same test using = like the original post?
Paul -
It doesn?t make a difference in Netlinx. I ran the tests and the results are the same either way.Interesting. Thanks for running the test. The = was changed to == though. I wonder if that made a difference. Can you run the same test using = like the original post?
Paul -
And for the record, the simplified version that jweather suggested returns exactly the same results also.
RETURN number & (1<<bit) != 0 -
a_riot42 is correct about precedence in C++, and the NetLinx programming manual shows operator precedence in approximately the same order (Principles of Programming page 41), with =, ==, and <> at level 5 and & at level 6. However, it doesn't seem to actually be implemented that way (anybody else shocked? no?)
Extra parens never hurt anything... if you're worried about it, just write (number & (1<<bit)) != 0 to ensure it evaluates the way you intended it. -
a_riot42 is correct about precedence in C++, and the NetLinx programming manual shows operator precedence in approximately the same order (Principles of Programming page 41), with =, ==, and <> at level 5 and & at level 6. However, it doesn't seem to actually be implemented that way (anybody else shocked? no?)
Extra parens never hurt anything... if you're worried about it, just write (number & (1<<bit)) != 0 to ensure it evaluates the way you intended it.
This does shock me. It's not that I am worried about it or being pedantic (not saying you are saying that) but if something as basic as operator precedence can't be relied upon it is a concern. Since Netlinx operator precedence is the same as most other languages I assume its a bug and not a mistake in the docs.
Paul -
I've never relied on precedence rules, because I can't rely on someone else reading my code to know them enough to figure out what's going on. So I always "force" precedence with parentheses when it's not just a simple operation.
There was a time in my early programming days that I went out of my way to write terse, ultra-tight code, and relied heavily on precedence rules to minimize the source footprint. But I've long since decided that it's just not worth it in this day of large memory pools. -
DHawthorne wrote: »I've never relied on precedence rules, because I can't rely on someone else reading my code to know them enough to figure out what's going on. So I always "force" precedence with parentheses when it's not just a simple operation.
There was a time in my early programming days that I went out of my way to write terse, ultra-tight code, and relied heavily on precedence rules to minimize the source footprint. But I've long since decided that it's just not worth it in this day of large memory pools.
I couldn't agree more, but that is no excuse for the compiler to compile code incorrectly. You have to be able to rely on the compiler to do what the docs say and not behave in an undefined way. Using parentheses is supposed to be for making the code more readable to humans, not for forcing the compiler to do what the docs say it should do, especially about something so basic as operator precedence.
Paul -
I couldn't agree more, but that is no excuse for the compiler to compile code incorrectly. You have to be able to rely on the compiler to do what the docs say and not behave in an undefined way. Using parentheses is supposed to be for making the code more readable to humans, not for forcing the compiler to do what the docs say it should do, especially about something so basic as operator precedence.
Paul
You are right, of course. I just thought that a good opening to share that particular viewpoint. I suppose it was a left-handed way of saying I never saw that particular bug because of my "readability" habit. -
I'm just adding to this post since I found it and it helped me sort out what I wanted. In my case I wanted to create an array of the bits in a byte and the code posted above will just let you know if a particular bit is set.
These are the variations I came up with:
DEFINE_FUNCTION CHAR[8]fnConvByteBitsToArray(CHAR iByte)//w/ $FF returns 1,1,1,1,1,1,1,1 (decimal or hex, won't see in ascii) { STACK_VAR INTEGER i; STACK_VAR CHAR cTmpArry[8]; for(i=0;i<=7;i++) { cTmpArry = "TYPE_CAST((iByte >> i ) & $01),cTmpArry"; } RETURN cTmpArry; } DEFINE_FUNCTION INTEGER[8]fnConvByteBitsToArray_1(CHAR iByte)//w/ $FF returns 1,1,1,1,1,1,1,1 { STACK_VAR INTEGER i; STACK_VAR INTEGER nTmpArry[8]; for(i=0;i<=7;i++) { nTmpArry[8-i] = TYPE_CAST((iByte >> i ) & $01); } RETURN nTmpArry; } DEFINE_FUNCTION INTEGER[8]fnConvByteBitsToArray_2(CHAR iByte)//w/ $FF returns 1,1,1,1,1,1,1,1 { STACK_VAR INTEGER i; STACK_VAR INTEGER nTmpArry[8]; for(i=0;i<=7;i++) { nTmpArry[8-i] = (iByte & ($01 << i) != 0); } RETURN nTmpArry; } DEFINE_FUNCTION INTEGER[8]fnConvByteBitsToArray_3(CHAR iByte)//w/ $FF returns 128,64,32,16,8,4,2,1 //returns the vlaue of its bit position if set { STACK_VAR INTEGER i; STACK_VAR INTEGER nTmpArry[8]; for(i=0;i<=7;i++) { nTmpArry[8-i] = TYPE_CAST(iByte & ($01 << i)); } RETURN nTmpArry; }For testing I just drop these else if's in my code and set the var values in debug which is why they're local var except for the nRunTest which is a global
else if(nRunTest==7) { LOCAL_VAR CHAR cCheckByte; LOCAL_VAR CHAR cBitArray[8]; cBitArray = fnConvByteBitsToArray(cCheckByte); } else if(nRunTest==8) { LOCAL_VAR CHAR cCheckByte1; LOCAL_VAR INTEGER nBitArray1[8]; nBitArray1 = fnConvByteBitsToArray_1(cCheckByte1); } else if(nRunTest==9) { LOCAL_VAR CHAR cCheckByte2; LOCAL_VAR INTEGER nBitArray2[8]; nBitArray2 = fnConvByteBitsToArray_2(cCheckByte2); } else if(nRunTest==10) { LOCAL_VAR CHAR cCheckByte3; LOCAL_VAR INTEGER nBitArray3[8]; nBitArray3 = fnConvByteBitsToArray_3(cCheckByte3); } if(nRunTest) { nRunTest=0; } -
And while this thread is resurrected, an AMX library posted by David Vine on GitHub:
https://github.com/AMXAUNZ/amx-util-library
Contains some functions for converting between "typical" data and ASCII strings containing binary representations of the data values. There's more in the library, but it's unfinished.
Could be worth to have a look.
Categories
- All Categories
- 2.5K AMX General Discussion
- 922 AMX Technical Discussion
- 514 AMX Hardware
- 502 AMX Control Products
- 3 AMX Video Distribution Products
- 9 AMX Networked AV (SVSI) Products
- AMX Workspace & Collaboration Products
- 3.4K AMX Software
- 151 AMX Resource Management Suite Software
- 386 AMX Design Tools
- 2.4K NetLinx Studio
- 135 Duet/Cafe Duet
- 248 NetLinx Modules & Duet Modules
- 57 AMX RPM Forum
- 228 MODPEDIA - The Public Repository of Modules for Everyone
- 943 AMX Specialty Forums
- 2.6K AMXForums Archive
- 2.6K AMXForums Archive Threads
- 1.5K AMX Hardware
- 432 AMX Applications and Solutions
- 249 Residential Forum
- 182 Tips and Tricks
- 146 AMX Website/Forums

