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.
Related
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.
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.
What are the purposes of ^ operator used in C other than to check if two numbers are equal? Also, why is it used for equality in stead of == in the first place?
The ^ operator is the bitwise XOR operator. Although I have never seen it's use for checking equaltity.
x ^ y will evaluate to 0 exatly when x == y.
The XOR operator is used in cryptography (en- and decrypting text using a pseudo-random bit stream), random number generators (like the Mersenne Twister) and in inline-swap and other bit twiddling hacks:
int a = ...;
int b = ...;
// swap a and b
a ^= b;
b ^= a;
a ^= b;
(useful if you don't have space for another variable like on CPUs with few registers).
^ is the Bitwise XOR.
A bitwise operation operates on one or more bit patterns or binary numerals at the level of their individual bits. It is a fast, primitive action directly supported by the processor, and is used to manipulate values for comparisons and calculations. (source: Bitwise Operation)
The XOR Operator has two operands and it returns 1 if only one of the operands is set to 1.
So a Bitwise XOR Operation of two numbers is the resulting of these bit by bit operations.
For exemple:
00000110 // A = 6
00001010 // B = 10
00001100 // A ^ B = 12
^ is a bit-wise XOR operator in C. It can be used in bits toggling and to swap two numbers;
x^=y, y^=x, x^=y;
and can be used to find max of two numbers;
int max(int x, int y)
{
return x ^ ((x ^ y) & -(x < y));
}
It can be used to selectively flip bits. (e.g. to toggle the value of bit #3 in an integer, you can say x = x ^ (1<<3) or, more compactly, x = x^0x08 or even x^=8. (although now that I look at it, the last form looks like some sort of obscene emoticon and should probably be avoided. :)
It should never be used in a test for equality (in C), except in tricky code meant to test undergrads' understanding of the ^ operator. (In assembly, there may be speed advantages on some architectures.)
It it's the exclusive or operator. It will do bitwise exclusive or on the two arguments. If the numbers are equal, this will result in 0, while if they're not equal, the bits that differed between the two arguments will be set.
You generally wouldn't use it inserted of ==, you would use it only when you need to know which bits are different.
Two real usage examples from an embedded system I worked on:
In a status message generating function, where one of the words was supposed to be a passthrough of an external device's status word. There was an disconnect between the device behavior and the message spec - one thought bit0 meant 'error' while the other thought it meant 'OK'.
statuswords[3] = devicestatus ^ 1; //invert B0
The 16-bit target processor was terribly slow to branch, so in an inner loop if (sign(A)!=sign(B) B=0; was coded as:
B*=~(A^B)>>15;
which took 4 cycles rather than 8, and does the same thing: sets B to 0 iff the sign bits are different.
in many general cases we might use '^' as a replacement for'==' but that doesn't exactly give the result for being equal or not.Instead - it checks the given variables bit by bit and sets a result for each bit individually and finally displays a result summed up with the resulting bits as a bulk.
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.
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".