![]() |
stream byter - binary logic math - midi messages - midi designer pro - dk70
This is all a bit "low level", but I needed that.
Bit operators for Stream Byter
MAT I0 = I0 & 0F # AND
MAT I0 = I0 | 0F # OR
MAT I0 = I0 ^ FF # XOR
|
Function: Switch off the AND 0 bits - make 0 of all 'AND 0' bits - and leave all AND 1 bits alone |
Hex to Binary table
* grey: filter with 1 * yellow: filter with 0 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Function: Switch on the OR 1 bits - make 1 of all 'OR 1' bits - and leave all OR 0 bits alone |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Function: Toggle the XOR 1 bits - toggle all 'XOR 1' bits - and leave all XOR 0 bits alone |
Binary math
AND "get bit value" |
1st | 2nd | 3rd | 4th |
select bit with 1 | 0001 | 0010 | 0100 | 1000 |
HEX select bit | 1 | 2 | 4 | 8 |
math | nibble AND 1 | nibble AND 2 | nibble AND 4 | nibble AND 8 |
result if was set | =1 | =2 | =4 | =8 |
result if was unset | =0 | =0 | =0 | =0 |
OR "set bit to 1" |
1st | 2nd | 3rd | 4th |
select bit with 1 | 0001 | 0010 | 0100 | 1000 |
HEX set bit | 1 | 2 | 4 | 8 |
math | nibble OR 1 | nibble OR 2 | nibble OR 4 | nibble OR 8 |
AND "set bit to 0" |
1st | 2nd | 3rd | 4th |
select bit with 0 | 1110 | 1101 | 1011 | 0111 |
HEX set bit | E | D | B | 7 |
math | nibble AND E | nibble AND D | nibble AND B | nibble AND 7 |
XOR "toggle bit" |
1st | 2nd | 3rd | 4th |
select bit with 1 | 0001 | 0010 | 0100 | 1000 |
HEX select bit | 1 | 2 | 4 | 8 |
math | nibble XOR 1 | nibble XOR 2 | nibble XOR 4 | nibble XOR 8 |
Most of the time, you can not use bitpatterns in your code. Unfortunately.
Everything has to be converted to hex or to dec first (binary boolean calculator).
So you need comments to explain what you did there.
Bottom line.
You basically need an "on" and "off" switch, a toggle switch and a "leave the bit alone" operator function.
You could do all this with just AND and OR, but the XOR is a nice addition, because it makes programming lazier.
Examples
AND (get value of one bit)
# TEST BIT 3 VALUE
result = 0111 AND 0100 # result = 0100, meaning bit 3 is 'On'
result = 7 & 4 # result = 4
# result for 'Off' is 0
# because you cunningly filtered out the rest of the bits with '0' so they are not a part of the result
# possible results for 'On' are 8, 4, 2 and 1, depending on which bit you tested
# however,
'>= 1' or 'not 0' would suffice, because you already know which bit you tested
# TEST BIT 3 VALUE
result = 1011 AND 0100 # result = 0000, meaning bit 3 is 'Off'
result = A & 4 # result = 0
OR (set one bit to 1)
# SET BIT 2 TO ON
result = 0100 OR 0010 # result = 0110, set bit 2 to 'On'
result = 4 | 2 # result = 6, which you can use to set the variable
AND (set one bit to 0)
# SET BIT 2 TO OFF
result = 0110 AND 1101 # result = 0100, set bit 2 to 'Off'
result = 6 & 13 # result = 4, the only calculation with a right part that has a higher number than the left
XOR (toggle one bit)
# TOGGLE BIT 3 VALUE
result = 0110 XOR 0100 # result = 0010
result = 6 ^ 4 # result = 2
So there. Very handy for working with SysEx messages.
And programming in assembly.
The next part is just for fun. Curiosity educates the cat.
Boolean Operators
The 4 possible results for logical operation on a bit:
- switch the bit on
- switch the bit off
- toggle the bit (from 1 to 0 or vice versa)
- don't change the bit
Every logical operator (AND, NOT, OR..) can only execute two ['what does 0 do, and what does 1 do'] of the above four possible operations in one go.
You could say that the operator is basically defined, by which 2 operations of the possible 4 it executes.
result = bitpatternA <operator> bitpatternB
The table focuses on what the right side (B) of the operator does to the left side (A) of the operator.
The table lists all possible (16 minus 2) results from 0001 to 1110 in the 'res' row.
The 2 results '0000' and '1111' are omitted, because the have no use.
The yellow cells show useless functions, or functions that can be achieved easily with existing operators.
See also Boolean Operators.
Question answered | B=1 | B=0 | Function | ||||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | NOR | Are both inputs off? | set A bit to 0 | toggle A bit | |
res | 0 | 0 | 0 | 1 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | ? | toggle the A bit | set A bit to 0 | ||
res | 0 | 0 | 1 | 0 | |||||
A | 1 | 1 | 0 | 0 | NOT | Is A off? | toggle every A bit | there is no B part | |
res | 0 | 0 | 1 | 1 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | ? | set A bit to 0 | leave the A bit alone | can be done with OR and NOT | |
res | 0 | 1 | 0 | 0 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | ? | set A bit to 0 | set A bit to 1 | pretty useless | |
res | 0 | 1 | 0 | 1 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | XOR | Are the inputs different? | toggle the A bit | leave the A bit alone | very handy for toggling a bit and leave the other bits alone |
res | 0 | 1 | 1 | 0 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | NAND | Is either input off? | toggle A bit | switch A bit to 1 | |
res | 0 | 1 | 1 | 1 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | AND | Are both inputs on? | leave the A bit alone | switch A bit to 0 | very handy for testing the state of A bit |
res | 1 | 0 | 0 | 0 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | XNOR | Are the inputs the same? | leave the A bit alone | toggle A bit | very handy for toggling a bit and leave the other bits alone. see also XOR |
res | 1 | 0 | 0 | 1 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | ? | switch A bit to 1 | switch A bit to 0 | useless | |
res | 1 | 0 | 1 | 0 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | IMPLIES | If A is on, is B also on? | set the A bit to 1 | toggle the A bit | |
res | 1 | 0 | 1 | 1 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | ? | leave the A bit alone | leave the A bit alone | useless | |
res | 1 | 1 | 0 | 0 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | ? | leave the A bit alone | switch A bit to 1 | can be done with OR | |
res | 1 | 1 | 0 | 1 | |||||
A | 1 | 1 | 0 | 0 | |||||
B | 1 | 0 | 1 | 0 | OR | Is either input on? | switch A bit to 1 | leave the A bit alone | very handy for 'switching-on' bits without destroying the other bits |
res | 1 | 1 | 1 | 0 |
result = bitpatternA <operator> bitpatternB
'On' and 'Off' are "hard settings". When an operator results in only hard settings, you don't need that operator and you might as well have set the value with a simple assign. Or, as one developer put it: "The best time to use them (truth tables) is when you map your logic and realize you have a function that takes two inputs, and has the same outputs as those operators :)".
result of A when | ||
B = 1 | B = 0 | operator |
on | on | no use |
off | no use | |
toggle | IMPLIES | |
no change | OR | |
![]() |
||
off | on | no use |
off | no use | |
toggle | NOR | |
no change | ||
![]() |
||
toggle | on | NAND |
off | ||
toggle | ||
no change | XOR | |
![]() |
||
no change | on | |
off | AND | |
toggle | XNOR | |
no change |
Funny that an on/off switch can have so much theory.