I am using ROBOTC to program my robot, and I was using some code built by someone else. In a function, I see the line:
int leftDir = (left>0)*2-1;
leftDir is initialized to an integer, so what does the > do? I am under the impression that is is a binary shift, but I'm not sure. Can someone explain this?
Thanks.
The > is the greater than operator. In C result of comparison is either 1 for true or 0 for false. In other words the code above is logically equivalent to (but more compact):
int leftDir;
if (left > 0) {
leftDir = 1;
} else {
leftDir = -1;
}
The previous answer is correct, but i believe he intended it as a bit shifting operator. This would make sense because he went on to multiply the value by a number, implying that he isn't treating it as a boolean. He was incorrect, though, about the roobtc bit shifting notation. If you want to bit shift a number in robotc, use the following syntax:
int foo = 0b00001111 >> 2; //bit shifts the bianary number 00001111 over by two bits, so foo will be set to the result 00000011
Related
I am analysing an Internet guide, where I fond code like that. Can somebody explain me the usage of ~ and & operators?
Thanks in advance
uint8_t tx_fifo_put(tx_dataType data)
{
/*Check if FIFO is full*/
if((tx_put_itr - tx_get_itr) & ~(TXFIFOSIZE-1))
{
/*FIFO full - return TXFAIL*/
return (TXFAIL);
}
/*Put data into fifo*/
TX_FIFO[tx_put_itr & (TXFIFOSIZE - 1)] = data;
/*Incerment itr*/
tx_put_itr++;
return(TXSUCCESS);
}
What the code does, is an obfuscated way to replace a more human readable code.
As a commenter wrote before me, the TX_FIFO[tx_put_itr & (TXFIFOSIZE - 1)] = data; loops the output. Also as it was mentioned in comments, the code is meant to have size being power of two.
I do not know why it is done so, for me TX_FIFO[tx_put_itr % TXFIFOSIZE] = data does the same, but more readable. Also, a person expects predicate checks to be before data access. At least it is my nature.
The (w - r) &~ size part is a way to check for (1)w < r and, (2) as an edge case, w being equal to FIFOSIZE and r being zero. Semantically it should have meant, that "if the write pointer points to boundary, and read pointer points to start of a buffer, we suggest that, for our data structure, next write could be an overflow."
Let us see some code, numbers and their binary representation.
let s = 8 - 1, in binary is 00000111 and negated is 11111000.
let w = 0, let r = 1.
now in binary w = 00000000, r = 00000001.
w - r = 11111111, logical and that with ~(8 - 1) and get some value, other then zero.
Continuing the logic for the w < r case, we get that any negative integer will produce some bits in the above. So this definitely gives true for the OP if code.
Now the w = r case can not commit bits to the boolean test.
And last case,
let s = 8,
let w = 8
let r = 0
w - r = 00001000
~(8 - 1) = 11111000
(w - r) &~ 7 = 00001000
All other cases where w > r give zero.
Update
To my great grief, the #UkropUkraine had deleted all comments and his answer. There were some discussion there about the fact, that one can use (w - r) >= mask in place of (w - r) & mask.
Here I present a code, and an explanation that it is not an optimization, or just syntax, or whatever came to mind to the person who wrote the OP code. It is intended code. And it fails to do its purpose: to run as a FIFO or circular queue, or whatever that part of code was meant to do.
First, take an example of usage. The part where Ukrop user had difficulties. The w pointer can be less than r pointer. And the result of w - r will be negative.
The common usage is to add a byte to the buffer and wrap write pointer as soon as it reaches the end. Imagine situation where w pointer already wrapped.
#include <stdio.h>
int main()
{
unsigned char w = 0, r = 1;
int r;
r = (a - b) & 0xffffffff;
printf("%d\n", r);
return 0;
}
-1
I do not know what is a common boolean result type with micro controllers. For a common x86 C machine, it is int. So I expect the if((w - r) &~ size) to be converted to an int. And the result is negative. You can not just write the above with >=, '>', or == as it was stated by the comments and the other answer here.
More than that, the code fails its semantics. It is meant to be a FIFO, or something, I do not know. But in the above situation, the read pointer still has some sensible data to read. And it can be done, because the write pointer, even if it is wrapped, does not overwrite the read portion of a buffer, yet. But the code returns BUFFULL.
I thought about read/write being different directions, but it does not change anything. The code OP gave, fails to do what one would expect.
Maybe I do miss some insight here, as Ukrop user, and OP, point me to the fact that they know code semantics. The OP just did not get a ~ and & usage. Well, this is an answer, the ~& is used to test for a negative value and for the edge cases.
The two operators:
& is a bitwise and operator
~ is a bitwise complement operator
Now for the posted code it's important to notice that TXFIFOSIZE must have a value which is a power of 2, i.e. values like 2, 4, 8, 16, 32, ...
When that is true, the code:
TX_FIFO[tx_put_itr & (TXFIFOSIZE - 1)] = data;
is equivalent to:
TX_FIFO[tx_put_itr % TXFIFOSIZE] = data;
Notice that tx_put_itr is being incremented in such a way that it will take value higher than TXFIFOSIZE. So in order to get a valid array index the code must find the remainder of tx_put_itr with respect to TXFIFOSIZE.
So how does work? Why are the above lines equivalent?
Let's take a value as example.
Assume TXFIFOSIZE is 8 (2 to the power of 3)
So TXFIFOSIZE-1 is 7
7 is bitwise 00....00111
And when you do:
SOME_NUMBER & 00....00111
You keep the 3 least significant bits of SOME_NUMBER
And that is exactly the remainder of when diving by 8
So let's look at
if((tx_put_itr - tx_get_itr) & ~(TXFIFOSIZE-1))
It is equivalent to
if((tx_put_itr - tx_get_itr) >= TXFIFOSIZE)
So it checks for "FIFO full"
Again using an example it works like this:
Assume TXFIFOSIZE is 8 (2 to the power of 3)
So TXFIFOSIZE-1 is 7
7 is bitwise 00....00111
~7 is bitwise 11....11000
And when you do:
SOME_NUMBER & 11....11000
You clear the 3 least significant bits of SOME_NUMBER and keep the rest unchanged
So if the result is non-zero it means that the difference between
tx_put_itr and tx_get_itr is 8 (or more).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Can anyone tell me how does this code work?
int Calc(int *arr, int m)
int result;
for (result &= 0; m; (arr[--m] & (0x1 << 0x1F)) ? result += arr[m]: Void());
return result;
I can't understand for loop:/
Where did you find this code so I can hunt that person down and beat him with a copy of Schildt?
It's no surprise you don't understand the loop; it wasn't written to be understandable. The only place this kind of code is acceptable is the IOCCC, except it's not obfuscated enough for that competition.
Taking each bit in turn:
result &= 0;
is a really funky way of initializing result to 0; it's shorthand for result = result & 0, which performs a bitwise-AND of result against 0 (giving 0) and assigns the result back to result. It's also unsafe, since an uninitialized object may contain a trap representation. That should have been written as simply result = 0.
m;
just checks the current value of m; the loop will run until it is 0. The loop basically starts at the last element and works its way down to the first.
(arr[--m] & (0x1 << 0x1F)) ? result += arr[m]: Void()
Ugh. So, the first thing it does is take the value of the array at index m-1 and does a bitwise and against 0x1 << 0x1F (1 shifted left 31 postitions, or essentially 0x80000000); if the result of this operation is non-zero, then we add the value of that array element to result, otherwise we execute some incredibly inappropriately named function that hopefully returns a 01. Given that we're dealing with signed integers, and that on most platforms an int is 32 bits wide, this code is obviously adding up negative values in result.
A slightly saner way of writing that would be
result = 0;
while ( m ) // or m != 0, or m > 0, whatever you prefer
{
if ( arr[--m] < 0 )
result += arr[m];
}
1. The conditional operator ?: isn't meant to be used as a control structure like this. The syntax is expr1 ? expr2 : expr3. First, expr1 is evaluated and all side effects applied; if it results in a non-zero value, then the result of the expression is expr2; otherwise, the result is expr3.
Part 1
Firstrly result &= 0 is used for setting 0 to result variable using bitwise AND operation. Bitwise with 0 will ever return 0.
You can write it simply this way: result = 0
The better (much optimal) way of doing this is: result ^= result. (Bitwise XOR)
Part 2
This loop will iterate while m is greater (or less) than 0. Because m expression will return true if m != 0.
Much secure way of doing it is m > 0.
Also you can use this expression, which is not making programm much optimal, but it will be cleaner to another programmer to understand your code: !!m (casting m variable to bool), which is equal to m != 0;
Part 3
In this part ternary operator (logical_expression ? expression_1 : expression_2) is used.
If logical_expression is true, then expression_1 will be executed, expression_2 will be executed otherwise.
So in your code, if this expression (arr[--m] & (0x1 << 0x1F)) returns true then we add arr[m] to result variable. And do nothing in another case.
Also m variable is decremented in ternary logical expression (arr[--m]).
What does the following condition if(a & (a-1)/2) mean in C?
#include <stdio.h>
int main()
{
int a;
scanf("%d", &a);
if(a & (a-1)/2)
{
printf("Yes\n");
}
else{
printf("No\n");
}
return 0;
}
I didn't get the meaning of / operator here. what does the division operator mean in the condition ?
The division operator / simply divides the left hand side by the right hand side. In this case the right hand side is 2, so it's shifting a-1 right by one bit (an arithmetic shift, which sign-extends the integer).
The whole expression therefore calculates - for a>=0 - whether a and ((a-1)>>1) both have any of the same bits set (in which case & will produce a non-zero value). For a<0 see the comment at the end.
Here's some test code:
#include <stdio.h>
#include <stdlib.h>
int
main (int argc, char **argv)
{
int i;
for (i = 0; i < 256; i++)
{
printf ("%3d %s\n", i, (i & (i - 1) / 2) ? "yes" : "no");
}
exit (0);
}
which gives
0 no
1 no
2 no
3 yes
4 no
5 no
6 yes
7 yes
8 no
9 no
10 no
11 yes
12 yes
13 yes
14 yes
15 yes
16 no
17 no
18 no
19 yes
20 no
21 no
22 yes
23 yes
24 yes
25 yes
26 yes
27 yes
28 yes
29 yes
30 yes
31 yes
32 no
33 no
34 no
... abbreviated for clarity ...
This detects numbers that either:
have two or more adjacent binary 1s or;
are negative, but not MININT.
Here's how:
If a>=0, then (a-1)/2 == a/2 (as rounding is always towards zero). So this is equivalent (for a>=0) to a & (a>>1) which will be one if the bit to the right of any bit in a is set, i.e. if there are two or more adjacent ones.
If a<0 and a!=MININT, (and thus have 1 as its MSB), then (a-1) must also be negative and less than -1, so (a-1)/2 must also be negative (and thus have 1 as its MSB), in which case a & ((a-1)/2)) is non-zero because its MSB must also be 1.
If a==MININT, then a-1 is MAXINT, so (a-1)/2 has no bits that are both 1.
For non-negative values, division by 2 is equivalent to shifting it 1 bit to the right. For negative values it is not equivalent, but I suspect that the authors of the code did not intend it to work with negative values.
(Note that this non-equivalence has nothing to do with exotic non-2's-complement architectures or arithmetic sifts. In C and C++ language signed division is required to round towards 0, which makes it impossible to implement signed division by a simple shift for negative values on 2's complement architectures. A post-shift correction is required.)
Now, as for what the whole a & (a - 1) / 2 expression is doing... Let's restrict consideration for non-negative values only.
Subtracting 1 is equivalent to inverting all trailing 0 bits in the number and then inverting the last (least significant) 1 bit. Division by 2 is equivalent to shift right by 1 bit.
In the context of & operation, the whole thing is equivalent to: kill the last 1 bit in a, shift the whole thing to the right 1 bit and & it with the original value.
I don't see the point of killing the last 1 bit in this case. It looks like for positive values the whole thing is equivalent to a & (a / 2) (i.e. to a & (a >> 1))), which simply detects if there are two adjacent 1 bits in the original a.
It substracts 1 from a then divides it by 2 and after that it makes a bit-and operation.
In the condition / operator simply does division. The only thing that matters is whether the result in condition is 0 (false) or not 0 (true).
As fot what the program actually does, it looks binary math related so you should ask someone who knows more about that.
In the expression a & (a - 1) / 2 there is a bitwise and operator, and a division operator. It is highly unusual that these are used together. Therefore, I don't know what the precedence is (does it divide a-1 by two and does a bitwise and with a, or does it do a bitwise and of a and a-1, then divide the result by two). I actually don't care what the precedence is, because I don't know what precedence the programmer writing the code assumed it would be.
If you see code like this, you need to find out what it does, you need to find out what it was intended to do, if both are the same you add parentheses to make the intent clear, and if they are not the same you have found a bug and figure out how it affects the program and what to do about it.
In the book I am reading to learn C "The C programming language" in chapter 2.
The book is explaining Bitwise operations and it has a function that shows how many bits are in an integer.
The following is the function...
int Bitcount(unsigned x){
int b;
for(b = 0; x != 0; x >>=1){
if(x & 01){
b++
}
}
return b;
}
Then an exercise is given to us stating exactly this.
"In a two's complement number system, x &= (x-1) deletes the rightmost 1-bit in x;
Explain why. Use this observation to write a faster version of Bitcount".
The problem is I really cannot understand how "x &= (x-1)" would work? can someone explain this to me? or send me to a resource that could better help me understand?
I have been trying to figure this out but I really can't.
Thank you for any help that you may give.
also if there is anything wrong with my question this is my first post so please help me make my questions better.
X and X-1 cannot both have their rightmost bit set to 1, because in the binary system numbers ending in 0 and 1 alternate - so X & (X-1) is guaranteed to be a number whose rightmost bit set to 0 as AND only evaluates to true if both terms are true. Maybe the confusion stems from what Andrew W said, here a bitwise AND is used (which ANDs each bit individually)?
EDIT: now, as Inspired points out, this is only part of the answer as the original problem specifies that the rightmost 1-bit will get reset. As Andrew W already answered the correct version in detail, I'm not going to repeat his explanation here but I refer to his answer.
It is equivalent to x = x & (x-1) Here, the & is a bitwise and, not a logical and.
So here's what happens:
1) The expression on the right will be evaluated first, and that value will be stored in x.
2) Suppose x = 01001011 in binary (this isn't the case, since more than 8 bits will be used to represent x, but pretend it is for this example). Then x-1 = 01001010.
3) compute the bitwise and:
01001011 &
01001010 =
01001010
which deleted the rightmost one bit.
now suppose number didn't end with a 1 bit:
Say: x = 01001100, the (x-1) = 01001011
compute the bitwise and:
01001100 &
01001011 =
01001000
again removing the rightmost 1.
Good book by the way. I hope you enjoy it!
Let's take a closer look at the rightmost 1 bit in x: suppose x = AAAAAA10000..0, where AAAAAA are arbitrary bits. Then x-1 = AAAAAA01111..1. Bitwise AND of these two expressions gives AAAAAA00000..0. This is how it resets the rightmost non-zero bit.
The problem is I really cannot understand how "x &= (x-1)" would work?
Binary number is positional the same way as decimal number. When we increase the number we carry a bit to the left, when we decrease we borrow from the left the same way we do with decimals. So in case x-01 we borrow the first 1-bit from the right while others being set to 1-bit:
10101000
- 00000001
--------
10100111
which is inversion of those bits till the first 1-bit. And as stated before by others ~y & y = 0 that is why this method can be used to count 1-bits as proposed by the book to make the method faster comparing to bits shifting.
If have a function which returns a negative number, 0, or a positive number. What I want instead is return -1 in case of a positive number, 0 in case of 0 and +1 in case of a positive number.
Can I achieve something like this using some sort of bit-fiddling or do I have to do ordinary comparisons?
You could use a test of sign bit, but aside from bringing assumptions about the integer size you'd still need to test for zero.
Instead I suggest the following "magic":
if (myvalue > 0)
return 1;
else if (myvalue < 0)
return -1;
else
return 0;
Clean, explicit, portable and indeed very fast on most compilers. The only plausible code-level optimization I'd suggest would be test for zero value first (or second) if you know this case to be is more frequent.
If you're looking for a neat expression:
return (val > 0) - (val < 0);
You definitely could achieve this by playing with the bits, but if you can't envision how to do it, you can't expect that people working with your code later will be able to read it.
Just use an if-else statement, your code will be simpler and you can move onto more important programming (or playing on SO :)).
If you're willing to assume 2s complement, that right-shift of a signed type is arithmetic (neither of those assumptions is portable, but they do hold for many common platforms), and you're really dead set on being too clever by half:
int number;
const int shift = sizeof number * CHAR_BIT - 1;
return (number >> shift) - (-number >> shift);
A bunch assumptions for something that's fairly cryptic, and no guarantee that it's actually faster on any given platform.
I'm going to assume that (a) you meant -1 for a negative number and (b) the range was -254 to +254.
Negative or positive could be evaluated by looking at only one bit, but to test for zero you're going to need to inspect all the bits to make sure they are all zero, which kind of defeats the purpose of using a bit manipulation "shortcut".
If I understood the question correctly:
static inline int sign(unsigned int n){
int sign_bit = n >> (sizeof(int)*CHAR_BIT - 1); //sign_bit = n<0 will also do
int is_zero = !n;
return 1 - is_zero - sign_bit * 2;
};
It's not "compressed" to show the logic.
If the integers are represented using 2's complement, then you need only look at the most significant bit. If it's a 1, then it's negative, otherwise it's positive or zero.
See also: 2's Complement
Don't look for bizarre bit magic, just divide the number by its magnitude and you'll get the sign.