the difference between ! and ~ in C in isNotEqual function - c

Hello I have been trying to do my homework in my Machine Organisation class.
I had to write code
/*
* Examples: isNotEqual(5,5) = 0, isNotEqual(4,5) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 2
*/
after some thinking I realized to write code
int isNotEqual(int x, int y) {
return x^y;
}
but it didn't work. after some searching I found a code that was similar to mine, but had !! in front of x^y.
int isNotEqual(int x, int y) {
return !!(x^y);
}
After finding this code I tried it and it worked. So I tried the same thing but with ~~ in front, but it didn't work. As I understand ! means not only "not " but it also does something else. Which is why we did !! (not+not=yes) twice to get the same value, but a different answer.
Am I correct about !!?
What does ! exactly do?
What is the difference between ~ and !?
When is the appropriate time to use ~ and when is the appropriate time to use !?

~ flips all the bits in a number. Flipping every bit twice, gives you back the same bits, so the number stays the same.
! gives you zero when applied to a non-zero operand and one when applied to zero. So if the operand is one or zero, it will give you back the same operand. But when the operand is neither one nor zero, it will give you back one instead of the original number.
So ~~ always gives you the original number and !! gives you one or zero.

! is using to get the opposite of a thing.
Opposite of true is false
Opposite of false is true
~ is using to change all bit by it opposite.
Opposite of false is true (1111 1111 ... is not equals to zero)
Opposite of true is not false (0000 0001 -> 1111 1110 not equals to zero so true and not false)
Use ! for logical proposal and ~ for binary operations.

The first you understand is that the xor operator x^y is the bit-manipulation operator that returns 0 only if the two bits are equal i.e, 1^1 and 0^0 is 0, while 1^0 and 0^1 is 1. So x^y is zero if all the bits of x and y are equal, non-zero otherwise.
The use of !! is that, a single ! returns an integer value of either 0 or 1, and a double !! returns the opposite of the previous result. If you think about it, that means, !! on a zero operand returns 0, while !! on a non-zero operand returns 1, exactly wha t you need.
~ is the bit-not operator, double ~~ returns the original number, it doesn't return only 0 or 1.

Related

C - less than or equal to with bitwise operators

I'm trying to create a function to determine whether x is less than or equal to y.
The legal operators are ! ~ & ^ | + << >>, and the function says "if x <= y then return 1, else return 0"
My thought process is to check whether x-y is negative, and then right shift 31 bits and compare with 1. No matter what adjustments I do, it returns 0, when it's expecting 1.
This is what I have so far:
int isLessOrEqual(int x, int y) {
return (((x - y) >> 31) & 1) | (!(x^y));
}
Can anyone please help me see what I'm doing wrong?
I also tried with all of these return statements:
return (!(x^y)) | (((x+(~y+1)) >> 31 ) & 1);
return ~(((x+(~y+1)) >> 31 ) & 1) | (!(x^y));
return !(((x+(~y+1)) >> 31 ) & 1) | (!(x^y));
return (((x+(~y+1)) >> 31 ) & 1);
return (((x+y+(~1)) >> 31 ) & 1) | (!(x^y));
return (((x+y+(~1) >> 31 ) & 1) | (!(x^y));
return (((x+(~y+1)) >> 31 ) & 0);
I am not going to do your assignment for you, but I will try to get you pointed in the right direction.
My thought process is to check whether x-y is negative, and then right shift 31 bits and compare with 1.
I take you to mean that you want to test whether x-y is negative by shifting the result and comparing with 1, and then to use that in determining the function's return value. That's more or less ok, but there is some room for concern about right shifting negative numbers, as the result is implementation defined. I do not think that's causing you trouble in practice, however.
No matter what adjustments I do, it returns 0, when it's expecting 1.
In some cases, yes. But there are many other cases where that approach, correctly implemented, produces the desired result. About 75% of cases, in fact. Specifically,
it works (only) when x-y does not overflow.
Additionally,
since you're not allowed to use the - operator, you'll need to perform the two's complement conversion and use + instead.
you can avoid the shifting by ANDing with INT_MIN instead of with 1. This yields a nonzero result (INT_MIN) when and only when the other operand of the & has its sign bit set. If you like, you can convert non-zero to exactly 1 by logically negating twice (!!x).
You can slightly simplify the overall computation by using y-x instead of x-y. Then you don't need special accommodation for the x == y case.
You know (or can know) that neither x - y nor y - x overflows when x and y have the same sign.* In that case, you can use one or another variation on testing the arithmetic difference of the arguments. On the other hand, there is a simpler alternative when the two have differing signs (left as an exercise).
To combine those into a single expression, you can compute bitmasks that effect a selection between two alternatives. Schematically:
return (WHEN_SIGNS_MATCH_MASK(x, y) & IS_DIFFERENCE_NON_NEGATIVE(y, x))
| (WHEN_SIGNS_DIFFER_MASK(x, y) & ...);
The WHEN_SIGNS_MATCH_MASK should evaluate to 0 when the signs differ and to -1 (== all bits 1) or another appropriate value when the signs are the same. The WHEN_SIGNS_DIFFER_MASK implements the opposite sense of that sign comparison. The IS_DIFFERENCE_NON_NEGATIVE expands to your subtraction-based computation, and the ... is the alternative approach for the differing-sign case. (I've implied using macros. You don't need to use macros, but doing so will probably make your code clearer.)
*A sufficient condition, but not a necessary one.

Clarification of a bitwise statement

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.

ROBOTC - Unsure about > notation

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

Replacing “!=” with bitwise operators

using only bitwise operators (|, &, ~, ^, >>, <<), is it possible to replace the != below?
// ...
if(a != b){
// Some code
}
/// ...
this is mainly out of self interest, since I saw how to do it with == but not !=.
if(a ^ b) {
//some code
}
should work.
You can also use your preferred method for == and add ^ 0xFFFFFFFF behind it (with the right amount of Fs to match the length of the datatype). This negates the value (same as ! in front of it).
a != b means that there is at least one different bit in the bit representations of a and b. The XOR bit operator returns 1 if both input bit operands are different, 0 otherwise.
So, you can apply a XOR operation to a and b and check if the result is not equal to zero.
A bitwise version of the '!=' test could look something like:
if((a - b) | (b - a)) {
/* code... */
}
which ORs the two subtractions. If the two numbers are the same, the result will be 0. However, if they differ (aka, the '!=' operator) then the result will be 1.
Note: The above snippet will only work with integers (and those integers should probably be unsigned).
If you want to simulate the '==' operator, however, check out Fabian Giesen's answer in Replacing "==" with bitwise operators
x ^ y isn't always sufficient. Use !!(x ^ y). Values expecting a one bit return value will not work with x ^ y since it leaves a remainder that could be greater than just 1.
Yes, using this:
if (a ^ b) { }
"~" is equaled to NOT so that should work. example would be "a & ~b".

Conditional Statement using Bitwise operators

So I see that this question has already been asked, however the answers were a little vague and unhelpful. Okay, I need to implement a c expression using only "& ^ ~ ! + | >> <<"
The expression needs to resemble: a ? b : c
So, from what I've been able to tell, the expression needs to look something like:
return (a & b) | (~a & c)
This works when a = 0, because anding it with b will give zero, and then the or expression will return the right side, (~a & c) which works because ~0 gives all ones, and anding c with all ones returns c.
However, this doesn't work when a > 0. Can someone try to explain why this is, or how to fix it?
I would convert a to a boolean using !!a, to get 0 or 1. x = !!a.
Then I'd negate that in two's complement. Since you don't have unary minus available, you use the definition of 2's complement negation: invert the bits, then add one: y = ~x + 1. That will give either all bits clear, or all bits set.
Then I'd and that directly with one variable y & b, its inverse with the other: ~y & c. That will give a 0 for one of the expressions, and the original variable for the other. When we or those together, the zero will have no effect, so we'll get the original variable, unchanged.
In other words, you need a to have all bits set to 0, if a is false (i.e. 0), and have all bits set to 1, if a is true (i.e. a > 0).
For the former case, the work is already done for you; for the latter -- try to work out result of the expression ~!1.

Resources