bitwise OR in iOS - c

enum {
UIViewAnimationOptionLayoutSubviews = 1 << 0,
UIViewAnimationOptionAllowUserInteraction = 1 << 1,
UIViewAnimationOptionBeginFromCurrentState = 1 << 2,
UIViewAnimationOptionRepeat = 1 << 3,
UIViewAnimationOptionAutoreverse = 1 << 4,
UIViewAnimationOptionOverrideInheritedDuration = 1 << 5,
UIViewAnimationOptionOverrideInheritedCurve = 1 << 6,
UIViewAnimationOptionAllowAnimatedContent = 1 << 7,
UIViewAnimationOptionShowHideTransitionViews = 1 << 8,
UIViewAnimationOptionCurveEaseInOut = 0 << 16,
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,
UIViewAnimationOptionTransitionNone = 0 << 20,
UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20,
UIViewAnimationOptionTransitionFlipFromRight = 2 << 20,
UIViewAnimationOptionTransitionCurlUp = 3 << 20,
UIViewAnimationOptionTransitionCurlDown = 4 << 20,
};
typedef NSUInteger UIViewAnimationOptions;
What exactly means this expression: UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse.
Value of UIViewAnimationOptionRepeat is equal to 8(in bin 1000), UIViewAnimationOptionAutoreverse is equal to 16(in bin 10000). So expression UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse should generate as I think 16(bin 10000) -> UIViewAnimationOptionReverse.

The operation | is defined by the truth table
| 0 | 1
---+---+---
0 | 0 | 1
1 | 1 | 1
that is, x | y == 0 only if both x == 0 and y == 0. The | operator works on all bits of a machine word at the same time. So
001000 (8)
| 010000 (16)
------------
011000 (24)

UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse is known as a "mask".
If you have a variable of type UIViewAnimationOptions, say:
UIViewAnimationOptions a;
you can apply the mask to it like this:
bool b = a && (UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse)
to determine if a "contains" either flags. If
a == 0x0000001;
then
b == false;
if
a == 0x0101001; //-- completely arbitrary mask
then
b == true;
So you are not actually interested in what UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse evaluates to, but only in the result of logically and-ing a value of that type to the flags you are interested in checking.

The bits are or'd:
UIViewAnimationOptionRepeat = 1 << 3 = 8 = 01000 in binary
UIViewAnimationOptionAutoreverse = 1 << 4 = 16 = 10000 in binary
01000
OR 10000
--------
11000
11000 in binary is 16 + 8 = 24 - an integer with third and fourth bits set (counting from 0).

UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
is equivalent to
01000
10000 |
the result of which is
11000
which is not 10000 as you had assumed.

Related

Why does data packing 4 integers into a 32 bit integer have different results in Nextion and Teensy(Arduino compatible)

I'm controlling a Teensy 3.5 with a Nextion touchscreen. On the Nextion the following code packs 4 8 bit integers into a 32 bit integer:
sys0=vaShift_24.val<<8|vaShift_16.val<<8|vaShift_8.val<<8|vaShift_0.val
Using the same shift amount (8) has a different result on the Teensy, however, the following generates the same result:
combinedValue = (v24 << 24) | (v16 << 16) | (v08 << 8) | (v00);
I'm curious why these shifts work differently.
Nextion documentation: https://nextion.tech/instruction-set/
//Nextion:
vaShift_24.val=5
vaShift_16.val=4
vaShift_8.val=1
vaShift_0.val=51
sys0=vaShift_24.val<<8|vaShift_16.val<<8|vaShift_8.val<<8|vaShift_0.val
//Result is 84148531
//Teensy, Arduino, C++:
value24 = 5;
value16 = 4;
value8 = 1;
value0 = 51;
packedValue = (value24 << 24) | (value16 << 16) | (value8 << 8) | (value0);
Serial.print("24 to 0: ");
Serial.println(packedValue);
packedValue = (value24 << 8) | (value16 << 8) | (value8 << 8) | (value0);
Serial.print("8: ");
Serial.println(packedValue);
//Result:
//24 to 0: 84148531
//8: 1331
Problem seems to be in this line:
sys0=vaShift_24.val<<8|vaShift_16.val<<8|vaShift_8.val<<8|vaShift_0.val
You are shifting by 8 in many places. Presumably you want:
sys0 = vaShift_24.val << 24 | vaShift_16.val << 16 | vaShift_8.val << 8 | vaShift_0.val
Now result from bytes 5, 4, 1, and 55 should be, in hex
0x05040133.
If you are instead seeing
0x33010405
it means you would also have a byte order issue. But probably not.

Using Bitwise Operators in C [duplicate]

This question already has answers here:
How does this work? Weird Towers of Hanoi Solution
(3 answers)
Closed 3 years ago.
I am a beginner to C language.I have a code for towers of hanoi but can someone explain me what are these bitwise operators doing ie if value of i is 1 what will be the source and target output value ?
source = (i & i-1) % 3;
target = ((i | i-1) + 1) % 3;
i & i-1 turns off the lowest set bit in i (if there are any set). For example, consider i=200:
200 in binary is 1100 1000. (The space is inserted for visual convenience.)
To subtract one, the zeros cause us to “borrow” from the next position until we reach a one, producing 1100 0111. Note that, working from the right, all the zeros became ones, and the first one became a zero.
The & produces the bits that are set in both operands. Since i-1 changed all the bits up to the first one, those bits are clear in the &—none of the changed bits are the same in both i and i-1, so none of them is a one in both. The other ones in i, above the lowest one bit, are the same in both i and i-1, so they remain ones in i & i-1. The result of i & i-1 is 1100 0000.
1100 0000 is 1100 1000 with the lowest set bit turned off.
Then the % 3 is selecting which pole in Towers of Hanoi to use as the source. This is discussed in this question.
Similarly i | i-1 turns on all the low zeros in i, all the zeros up to the lowest one bit. Then (i | i-1) + 1 adds one to that. The result is the same as adding one to the lowest one bit in i. That is, the result is i + x, where x is the lowest bit set in i. Using our example value:
i is 1100 1000 and i-1 is 1100 0111.
i | i-1 is 1100 1111.
(i | i-1) + 1 is 1101 0000, which equals 1100 1000 + 0000 1000.
And again, the % 3 selects a pole.
A quick overview of bitwise operators:
Each operator takes the bits of both numbers and applies the operation to each bit of it.
& Bitwise AND
True only if both bits are true.
Truth table:
A | B | A & B
-------------
0 | 0 | 0
1 | 0 | 0
0 | 1 | 0
1 | 1 | 1
| Bitwise OR
True if either bit is true.
Truth table:
A | B | A | B
-------------
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 1
^ Bitwise XOR
True if only one bit is true.
Truth table:
A | B | A ^ B
-------------
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 0
~ Bitwise NOT
Inverts each bit. 1 -> 0, 0 -> 1. This is a unary operator.
Truth table:
A | ~A
------
0 | 1
1 | 0
In your case, if i = 1,
the expressions would be evaluated as:
source = (1 & 1-1) % 3;
target = ((1 | 1-1) + 1) % 3;
// =>
source = (1 & 0) % 3;
target = ((1 | 0) + 1) % 3;
// =>
source = 0 % 3;
target = (1 + 1) % 3;
// =>
source = 0;
target = 2 % 3;
// =>
source = 0;
target = 2;
Good answer above, here is a high-level approach:
i == 1:
source: (1 & 0). Are both of these values true or >= 1? No they are not. So the overall result is 0, 0 % 3 = 0.
target: ((1 | 0) + 1) % 3.
(1 | 0) evaluates to 1(true) since one of the two values on the sides of the | operator are 1, so now we have (1 + 1). so then it follows we have 2 % 3 = 2.
Source: 0, target: 2

How can I interpret << and | in C

I need help to understand what is happening in this declaration:
#define LDA(m) (LDA_OP << 5 | ((m) & 0x001f))
Thank you
y << x is a left shift of y by x.
x & y is a bitwise and of x and y.
So, the left shift operator is like multiplying by 10 in base 10, but instead you multiply for 2 in base 2, for example:
In base 10
300 * 10 = 3000
In base 2:
0b0001 * 2 = 0b0010 = 0b0001 << 1
with a << b you "push" the number a, b places to the left.
and the or operator ( | )
you have to take two bits and if one or both of them are true (1) then the result is true.
For example:
0b0010 | 0b0001 = 0b0011
0b0010 | 0b0010 = 0b0010
If you have problems with this operators, just try to work the same numbers but in binary.

Why is 1 << 3 equal to 8 and not 6? [duplicate]

This question already has answers here:
What are bitwise shift (bit-shift) operators and how do they work?
(10 answers)
Closed 8 years ago.
In C I have this enum:
enum {
STAR_NONE = 1 << 0, // 1
STAR_ONE = 1 << 1, // 2
STAR_TWO = 1 << 2, // 4
STAR_THREE = 1 << 3 // 8
};
Why is 1 << 3 equal to 8 and not 6?
Shifting a number to the left is equivalent to multiplying that number by 2n where n is the distance you shifted that number.
To see how is that true lets take an example, suppose we have the number 5 so we shift it 2 places to the left, 5 in binary is 00000101 i.e.
0×27 + 0×26 + 0×25 + 0×24 + 0×23 + 1×22 + 0×21 + 1×20 = 1×22 + 1×20 = 4 + 1 = 5
now, 5 << 2 would be 00010100 i.e.
0×27 + 0×26 + 0×25 + 1×24 + 0×23 + 1×22 + 0×21 + 0×20 = 1×24 + 1×22 = 16 + 4 = 20
But we can write 1×24 + 1×22 as
1×24 + 1×22 = (1×22 + 1×20)×22 = 5×4 → 20
and from this, it is possible to conclude that 5 << 2 is equivalent to 5×22, it would be possible to demonstrate that in general
k << m = k×2m
So in your case 1 << 3 is equivalent to 23 = 8, since
1 << 3 → b00000001 << 3 → b00001000 → 23 -> 8
If you instead did this 3 << 1 then
3 << 1 → b00000011 << 1 → b00000110 → 22 + 21 → 4 + 2 → 6
1 in binary is 0000 0001
by shifting to left by 3 bits (i.e. 1 << 3) you get
0000 1000
Which is 8 in decimal and not 6.
Because two to the power of three is eight.
Think in binary.
You are actually doing this.
0001 shifted 3 times to the left = 1000 = 8

Implementing logical negation with only bitwise operators (except !)

~ & ^ | + << >> are the only operations I can use
Before I continue, this is a homework question, I've been stuck on this for a really long time.
My original approach: I thought that !x could be done with two's complement and doing something with it's additive inverse. I know that an xor is probably in here but I'm really at a loss how to approach this.
For the record: I also cannot use conditionals, loops, ==, etc, only the functions (bitwise) I mentioned above.
For example:
!0 = 1
!1 = 0
!anything besides 0 = 0
Assuming a 32 bit unsigned int:
(((x>>1) | (x&1)) + ~0U) >> 31
should do the trick
Assuming x is signed, need to return 0 for any number not zero, and 1 for zero.
A right shift on a signed integer usually is an arithmetical shift in most implementations (e.g. the sign bit is copied over). Therefore right shift x by 31 and its negation by 31. One of those two will be a negative number and so right shifted by 31 will be 0xFFFFFFFF (of course if x = 0 then the right shift will produce 0x0 which is what you want). You don't know if x or its negation is the negative number so just 'or' them together and you will get what you want. Next add 1 and your good.
implementation:
int bang(int x) {
return ((x >> 31) | ((~x + 1) >> 31)) + 1;
}
The following code copies any 1 bit to all positions. This maps all non-zeroes to 0xFFFFFFFF == -1, while leaving 0 at 0. Then it adds 1, mapping -1 to 0 and 0 to 1.
x = x | x << 1 | x >> 1
x = x | x << 2 | x >> 2
x = x | x << 4 | x >> 4
x = x | x << 8 | x >> 8
x = x | x << 16 | x >> 16
x = x + 1
For 32 bit signed integer x
// Set the bottom bit if any bit set.
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x ^= 1; // Toggle the bottom bit - now 0 if any bit set.
x &= 1; // Clear the unwanted bits to leave 0 or 1.
Assuming e.g. an 8-bit unsigned type:
~(((x >> 0) & 1)
| ((x >> 1) & 1)
| ((x >> 2) & 1)
...
| ((x >> 7) & 1)) & 1
You can just do ~x & 1 because it yields 1 for 0 and 0 for everything else

Resources