I'm wondering how to best deal with multiple flag cases, for example I have 5 flags that I need to check: t d y r g and I need to check all cases of such flags. What is a better way of doing so instead of,
if(t && d && y && r && g) {}
else if(t && d && y && r) {}
else if(t && d && y && g) {}
....
else if(t) {}
else if(d) {}
You could convert the flags to single bits and perform binary operations on them.
Assume there are five flags: a, b, c, d, and e.
Valid values for all flags are 0x1 and 0x0.
Convert to uint8_t:
uint8_t flags;
flags |= a;
flags |= b << 0x1;
flags |= c << 0x2;
flags |= d << 0x3;
flags |= e << 0x4;
flags |= f << 0x5;
If you stored all flags in an array from the beginning and denoted them via macros as indices like this:
#define IGNORE_CASE 0x0
...
bool flag_array[NUM_FLAGS];
flag_array[IGNORE_CASE] = SOME_VALUE;
the whole conversion process could be simplified to a loop.
Now you can conveniently compare with specific bit masks.
To check if a and b are set, use
if (flags & (0x1 + 0x2))
To check if b and f are set, use
if (flags & (0x2 + 0x20))
The cleaner way would be to define macros or constants for the flag bit masks and use these macros, not the plain hexadecimal bit masks.
Related
I am using java SWT, which has a bunch of bit flags and operations I can use, but I'm not familiar with them.
To better explain, I have a style
style = SWT.A | SWT.B
Which basically translates to having style A AND B. I know that this is because
A = 0001
B = 0100
A | B = 0101 (bitwise or)
But I haven't played with bits enough to know all the things I can do, this is all I know
style |= A; // style adds flag A
style &= ~B; // style removes flag B
Do I have something like +0 at my disposal? For ternary operations.
style ?= question ? "+ style A" : "as is, no change"
I'm thinking maybe
style = question ? style | A : style;
style = question ? style & ~B : style;
But I'm not sure.
Anything else that would be useful?
There is also exclusive OR.
Exclusive OR (aka XOR) says in shorthand, one or the other but not both. So if you XOR 0 and 1 together it will return a 1. Otherwise a 0. And don't forget that these bitwise operators also operate on boolean values.
int A = 0b0001;
int B = 0b0100;
// A | B = 0101 (bitwise or)
style ^= A; // If off, turn on. If on, turn off.
style = A|B; // 0101
style ^= A; // style now equals 0100
style ^= A; // style now equals 0101
You can also swap with it.
int a = 23;
int b = 47;
a ^= b;
b ^= a;
a ^= b;
Now a == 47 and b == 23
And lastly, there is another use for bitwise operators. Defeating short circuiting of if statements. Here is an example:
int a = 5;
int b = 8;
// here a is true, no need to evaluate second part, it is short circuited.
if (a == 5 || ++b == 7) {
System.out.println(a + " " + b);
}
// but here the second part is evaluated and b is incremented.
if (a == 5 | ++b == 7) {
System.out.println(a + " " + b);
}
I can't remember every using it this way and it can cause difficult to find bugs in your program. But it's a feature.
byte x = 0x0c;
byte y = 0x05;
System.out.println((x&0xf) + (y&0xf)); // if > 15 then af on
System.out.println((b&0xf) - (c&0xf));
System.out.println((int)(b&0xff) + (c&0xff)); // if > 255 then cf on
System.out.println(((int)(b&0xff) + (c&0xff)) & 0b10000000); // if 128 sign flag set
System.out.println((int)(b&0xff) - (c&0xff)); // if less than 0 then cf set
System.out.println(((int)(b&0xff) - (c&0xff)) & 0b10000000); //if 128 then sign flag set
I am building an 8085 simulator, and under the Arithmetic & Logical Instructions, I was trying to find a reliable method to check when to set or unset the 5 flags.
Out of the 5, sign flag, zero flag and parity flag are easy to check for, however carry and auxiliary carry flag gets complex. My method of approaching to check the carry flag & auxiliary carry flag are posted above which don't seem very reliable.
Any better/cleaner/more optimal solution is welcome. I have also been using www.sim8085.com to check my mini code snippets and check which flags are getting turned on, here is where I arrived at my next question :
mvi a, ffh
mvi b, cch
sub b
hlt
When I run this code, the auxiliary flag gets set. From what I know, the auxiliary flag only gets set if there is a carry from the lower nibble to the higher nibble. Hence I'm not being able to understand the logic behind the same.
Would also like to know if all flags are only affected by changes to accumulator or otherwise as well?
EDIT:
byte b = 0x2f;
byte c = 0x2c;
byte d = (byte) ((byte) (b&0xf) + (c&0xf));
byte e = (byte) ((byte) (b&0xf) + ((~c)&0xf) + 1);
int x = (int) ((b&0xff) + (c&0xff));
int y = (int) ((int) (b&0xff) + ((~c)&0xff) + 1);
System.out.println(y);
System.out.println((d>0xf) + "\t" + (e>0xf));
System.out.println((x>0xff) + "\t" + (y>0xff));
I tried using this logic to see if it works for all mathematical operations, apparently this doesn't make it as well to reliably check if carry or auxiliary carry flag should be set. Kindly help me figure out how to reliably check if an operation results in carry flag and auxiliary carry flag being set or unset.
byte b = (byte) 0x1c;
byte c = (byte) 0xff;
char a = (char) (Byte.toUnsignedInt(b) + Byte.toUnsignedInt(c));
char d = (char) (Byte.toUnsignedInt(b) - Byte.toUnsignedInt(c));
System.out.println(Integer.toHexString(a));
System.out.println(Integer.toHexString(d));
if(a > 0xff) {
System.out.println("Add Carry");
}
if(d > 0xff) {
System.out.println("Sub Carry");
}
if((Byte.toUnsignedInt(b) & 0xf) + (Byte.toUnsignedInt(c) & 0xf) > 0xf) {
System.out.println("Add Aux Carry");
}
if((Byte.toUnsignedInt(b) & 0xf) + (Byte.toUnsignedInt((byte) ~c) & 0xf) + 1 > 0xf) {
System.out.println("Sub Aux Carry");
}
I did some further checking and figured char data type is unsigned in java and hence it can be used with the logic above for the required results.
I'm trying to make bytes out of a source of individual bits /booleans in the Java language. I'd like the routine to run as quickly as possible, and I'm after the unsigned flavour of byte. I've done some internet searches, but can't actually find any code specifically for this.
All I can come up with is the following, which seems amateurish. I'm aware of the BitSet, but those are internally represented as Longs (I'm using a 32 bit machine so double handling) and it has a huge API so I expect it to be slow. Can there be anything more efficient, perhaps at low level?
public int nextByte() {
int b = 0;
for (int k = 0; k < 7; k++) {
if (nextBoolean()) {
b++;
}
b = b << 1;
}
if (nextBoolean()) {
b++;
}
return b;
}
This should be as efficient as it can be:
public int nextByte() {
int b = nextBoolean() ? 0x80 : 0;
if (nextBoolean()) b = b | 0x40;
if (nextBoolean()) b = b | 0x20;
if (nextBoolean()) b = b | 0x10;
if (nextBoolean()) b = b | 0x08;
if (nextBoolean()) b = b | 0x04;
if (nextBoolean()) b = b | 0x02;
if (nextBoolean()) b = b | 0x01;
return b;
}
If you wish to try really, really hard, you may use:
public int nextByte() {
return
(nextBoolean() ? 0x80 : 0)
| (nextBoolean() ? 0x40 : 0)
| (nextBoolean() ? 0x20 : 0)
| (nextBoolean() ? 0x10 : 0)
| (nextBoolean() ? 0x08 : 0)
| (nextBoolean() ? 0x04 : 0)
| (nextBoolean() ? 0x02 : 0)
| (nextBoolean() ? 0x01 : 0);
}
If this were C language, this last solution would not be guaranteed to work, as the C standard says calls to nextBoolean() may occur in any order the compiler sees fit. However, the Java Language Specification, section 15.7, guarantees (apparent) strict left-to-right evaluation, so in Java bits are guaranteed to go in the correct order. On the other hand, the next sentence explicitly recommends code to "not rely crucially on this specification" and that "code is usually clearer when each expression contains at most one side effect". Of course, calling nextBoolean() is a textbook example of "a side effect", and doing it 8 times in a single expression goes against the recommendation.
Furthermore (and most importantly, and in line with other answers), I say the most computationally expensive part of these solutions (or yours, for that matter) is probably the eight calls to nextBoolean() and not the loop or the conditionals, so I don't think you can get this going visibly faster without avoiding those calls.
I have some data in field type Byte ( I save eight inputs in Byte, every bit is one input ).
How to change just one input in that field ( Byte) but not to lose information about others ( example change seventh bit to one, or change sixth bit to zero )?
To set the seventh bit to 1:
b = (byte) (b | (1 << 6));
To set the sixth bit to zero:
b = (byte) (b & ~(1 << 5));
(The bit positions are effectively 0-based, so that's why the "seventh bit" maps to 1 << 6 instead of 1 << 7.)
Declare b as the primitive type byte:
byte b = ...;
Then you can use the compound assignment operators that combine binary operations and assignment (this doesn't work on Byte):
b |= (1 << bitIndex); // set a bit to 1
b &= ~(1 << bitIndex); // set a bit to 0
Without the assignment operator you would need a cast, because the result of the | and & operations is an int:
b = (byte) (b | (1 << bitIndex));
b = (byte) (b & ~(1 << bitIndex));
The cast is implicit in the compound assignment operators, see the Java Language Specification.
To set a bit use :
public final static byte setBit(byte _byte,int bitPosition,boolean bitValue)
{
if (bitValue)
return (byte) (_byte | (1 << bitPosition));
return (byte) (_byte & ~(1 << bitPosition));
}
To get a bit value use :
public final static Boolean getBit(byte _byte, int bitPosition)
{
return (_byte & (1 << bitPosition)) != 0;
}
Note that the "Byte" wrapper class is immutable, and you will need to work with "byte".
You really owe it to yourself to look into masking functions for and, or, and xor -- they allow you to simultaneously verify, validate, or change... one, some, or all of the bits in a byte structure in a single statement.
I'm not a java programmer by trade, but it's derived from C and a quick search online seemed to reveal support for those bitwise operations.
See this Wikipedia article for more information about this technique.
While reading the Android guide to Notifications, I stumbled across this:
Adding vibration
You can alert the user with the the default vibration pattern or with a
vibration pattern defined by your application.
To use the default pattern, add "DEFAULT_VIBRATE" to the defaults field:
notification.defaults |= Notification.DEFAULT_VIBRATE;
What this does is clear: it adds the DEFAULT_VIBRATE flag to the default flags of the notification object.
But what does the |= operator do in Java?
It looks like an "OR", but how does it work?
Can you provide an example using numbers?
Thanks
|= is a bitwise-OR-assignment operator. It takes the current value of the LHS, bitwise-ors the RHS, and assigns the value back to the LHS (in a similar fashion to += does with addition).
For example:
foo = 32; // 32 = 0b00100000
bar = 9; // 9 = 0b00001001
baz = 10; // 10 = 0b00001010
foo |= bar; // 32 | 9 = 0b00101001 = 41
// now foo = 41
foo |= baz; // 41 | 10 = 0b00101011 = 43
// now foo = 43
a |= x is a = a | x, and | is "bitwise inclusive OR"
Whenever such questions arise, check the official tutorial on operators.
Each operator has an assignment form:
+= -= *= /= %= &= ^= |= <<= >>= >>>=
Where a OP= x is translated to a = a OP x
And about bitwise operations:
0101 (decimal 5)
OR 0011 (decimal 3)
= 0111 (decimal 7)
The bitwise OR may be used in situations where a set of bits are used as flags; the bits in a single binary numeral may each represent a distinct Boolean variable. Applying the bitwise OR operation to the numeral along with a bit pattern containing 1 in some positions will result in a new numeral with those bits set.
It is a short hand notation for performing a bitwise OR and an assignment in one step.
x |= y is equivalent to x = x | y
This can be done with many operators, for example:
x += y
x -= y
x /= y
x *= y
etc.
An example of the bitwise OR using numbers.. if either bit is set in the operands the bit will be set in the result. So, if:
x = 0001 and
y = 1100 then
--------
r = 1101
In this case, notification.defaults is a bit array. By using |=, you're adding Notification.DEFAULT_VIBRATE to the set of default options. Inside Notification, it is likely that the presence of this particular value will be checked for like so:
notification.defaults & Notification.DEFAULT_VIBRATE != 0 // Present
This is the bit wise OR operator. If notifications.default is 0b00000001 in binary form and Notification.DEFAULT_VIBRATE is 0b11000000, then the result will be 0b11000001.
bitwise OR operator