Check if a number is in a range [duplicate] - c

This is part of a puzzle that I can't figure out. The function takes in three inputs. The first is an int, the second is the lower bound and the third is the upper bound. I need to test to see if that first number is within the lower and upper bound inclusive.
If it is in range then return 1, else return 0.
The catch is that I can only use
! ~ & ^ | + << >>
operations and only a combination of 20 of them.. Also, only int variables may be used, and no if statements, loops or function calls.
Range(int x, int lower, int upper){
//... some code here
return retVal;
}
Obviously I understand the logic here. If((x >= lower) && (x <= upper)) return 1;
The only problem is that I can't use if statements, <, >, ==, or &&.

You can make the comparison predicate x < y (returning -1 if true, 0 if false) like this: (see Hacker's Delight, Chapter 2, sub-chapter Comparison Predicates)
((x - y) ^ ((x ^ y) & ((x - y) ^ x))) >> 31;
You didn't list subtraction, but you can emulate x - y with ~(~x + y)
Using two of these predicates, make 1 & ~((x < lower) | (upper < x))
This obviously assumes 2's complement negatives and 32 bit integers with wrapping on overflow. So this is not portable, but that's the norm with this kind of trick.
As requested, that makes the total thing:
int in_range(int x, int lower, int upper)
{
int p = ((x - lower) ^ ((x ^ lower) & ((x - lower) ^ x))) >> 31;
int q = ((upper - x) ^ ((upper ^ x) & ((upper - x) ^ upper))) >> 31;
return 1 & ~(p | q);
}
It still has the subtractions, they're trivial to replace if you really want.
It's possible to make it a tiny tiny bit shorter by using the >= and <= predicates (which can also be found in Hacker's Delight).
Here's my website saying it's correct.
And here's a way that uses less operations, keeping in mind we can't use subtraction:
int p = (x | ~upper) & ((x ^ upper) | (~upper + x));
int q = (lower | ~x) & ((lower ^ x) | (~x + lower));
return 1 & ((p & q) >> 31);
It uses the <= predicate from HD, which looks like (x | ~y) & ((x ^ y) | ~(y - x)) in its pure form.
And here's my website saying it's correct.

Here is a humble solution
int foo(int num, int upp, int low){
return (~((~(upp + ~num + 1)) ^ (~(num + ~low + 1))) >> 31) & 1;
}

do this. i'll tell the logic that can be used.
a=~x+1 //gives -x
b=lower+a //lower-x
c=~upper+1 //gives -upper
d=x+c //x-upper
b=b&0x80000000; //get the msb which is 1 if -ve number
d=d&0x80000000;
return ((b&d)|(!(x^lower))|(!(x^upper))); //& results in +ve only if both b & d are +ve

I'm liking these puzzles you have! For this you will want to have something like,
Ok to be abstract on this one, you will want to have 2 variables.
The first variable (lets call it blarg) you need to set the upper bound and add the flipped x.
Now you will want to add one to blarg and flip it.
Your second variable (lets call it hold) will add the x to the flipped lower bound; After that add 1 to hold and flip it too.
set blarg = to the blarg plus hold;
shift blarg over 31 to the the right.
and AND it with 1.
Should be what you are looking for.

Related

Make a function that returns 1 if x < y , otherwise return 0

Editor's note: This is one quiz from CS:APP Data Lab, where the intention is to teach 2's complement integer representation (so please don't comment about poor C practices). There are extra assumptions and restrictions over ISO C:
int is 32 bits, using 2's complement representation
Signed integer overflow wraps around (-fwrapv)
Right-shifting is arithmetic on signed types, i.e., the MSB is duplicated to fill in the shifted bits
As part of a coding project in my coding class, one that teaches C, we were given a number of bit manipulation questions with restrictions. Seen here:
CheckIfLess - if x < y then return 1, else return 0
* Example: CheckIfLess(4,5) = 1.
* Legal operations: ! ~ & ^ | + >>
* Max ops: 13
*/
Besides the legal operations listed, I can't use any statements such as do, if, while, or else. I can't cast to other data types either. Also I can't use any constant bigger than 0xFF, not that I think it'll come up for this problem. Also, assume we are using a 32 bit machine.
Here is my code so far:
int CheckIfLess(int x, int y) {
int xSign, ySign, same, diffSign, ovfTrue, ovfFalse;
same = !(x ^ y); //1 if same, else 0
xSign = x >> 31; //get sign of x
ySign = y >> 31; //get sign of y
diffSign = (x + ~y + 1) >> 31; //(x - y) then checking if they have a diff sign
// These are for overflow cases
ovfTrue = xSign & ~ySign;
ovfFalse = xSign | ~ySign;
return !!((ovfTrue | ~diffSign) & ovfFalse);
}
One thing that I know everyone will point out is that the 'same' variable isn't implemented in the answer. This is because I'm not sure were to put it to be honest. Also, I'm already 3 operations over the limit, so I need to cut out some stuff.
Could you explain your answers to me really well, I've only been learning C for just shy of a month. Also, can you explain how I'd go about reversing the function so that it would return 1 if x > y instead of x < y, else return 0?
Edit: I can't use -. I'm just supposed to use the legal operations listed in the first code chuck
Edit2: Updated my notes on the code based on what I think each statement does. Changed the x - y statement to actually be x - y instead of y - x.
Edit3: added bolded question at bottom
If x and y have different sign bits, then we only have to check if x is negative.
Else, we can check if x-y is negative
That would be:
return (x<0 != y<0) ? (x<0) : (x-y)<0;
Let's now rewrite those operations with the ones we have:
t < 0 ==> t >> 31
x-y ==> x + ~y + 1
c ? t : f ==> c & t | ~c & f // (c&(t^f))^f (-1 ops)
a != b ==> a^b
That gives us (13 ops):
sign_x = x >> 31;
sign_y = y >> 31;
sign_xy = sign_x ^ sign_y;
x_minus_y = x + ~y + 1;
sign_x_minus_y = x_minus_y >> 31;
x_lt_y = sign_xy & sign_x | ~sign_xy & sign_x_minus_y;
return !!x_lt_y; // x_lt_y & 1 (-1 ops)
We can further simplify (9 ops) by extracting the ">>31" operation, that is a>>31 # b>>31 == (a # b)>>31 where # is one of &, |, ^:
xy = x ^ y;
x_y = x + ~y + 1;
x_lt_y = (xy & (x ^ x_y)) ^ x_y;
return (x_lt_y>>31) & 1;
All the other comparisons can be obtained as such:
x > y is (y < x)
x <= y is !(y < x)
x >= y is !(x < y)
x == y is !(y<x | x<y)
x != y is !!(y<x | x<y)

Greater than function in C

I know this is an age old question and you probably have come across this aswell, but there's a bug in my solution and I don't know how to solve it. I need to write a function that compares two integers. I am only allowed to use the operations (!,~,&,^,|,+,>>,<<) and also no control structures(if,else loops etc).
isGreater(int x, int y) {
//returns 1 if x > y.
return ((y+(~x+1))>>31)&1;
}
my idea is simple, we compute y-x, we shift by 31 to get the sign bit, if it's negative, then we return zero else we return 1. This fails when x is negative and falsly returns 1 although it should return zero. I'm stuck at this and don't know how to proceed.
We assume that integer is 32bits and uses two's complement representation. This question is NOT about portability.
Some help would be much appreciated.
Thanks in advance
Hacker's Delight has a chapter Comparison Predicates, which is exactly what we need here.
One of the things it writes is:
x < y: (x - y) ^ ((x ^ y) & ((x - y) ^ x))
Which we can use almost directly, except that x and y should be swapped, the subtractions must be replaced by something legal, and the result appears in the top bit instead of the lowest bit. Fortunately a - b == ~(~a + b) so that's not too hard. First applying those transformations:
// swap x <-> y
(y - x) ^ ((y ^ x) & ((y - x) ^ y))
// rewrite subtraction
~(~y + x) ^ ((y ^ x) & (~(~y + x) ^ y))
// get answer in lsb
((~(~y + x) ^ ((y ^ x) & (~(~y + x) ^ y))) >> 31) & 1
I have a website here that says it works.
If local variables are allowed it can be simplified a bit by factoring out the subexpression
~(~y + x):
int diff = ~(~y + x);
return ((diff ^ ((y ^ x) & (diff ^ y))) >> 31) & 1;
First of all let's clarify that we assume:
negative integers are represented in 2's complement
int is exactly 32 bits wide and long long is exactly 64 bits wide
right shifting a negative number is an arithmetic shift
There is a problem with the (~x+1) part in your solution which is supposed to return -x. The problem is that the absolute value of INT_MIN is greater than the absolute value of INT_MAX, thus when x is INT_MIN then (~x+1) yields INT_MIN instead of -INT_MIN as you expected.
There's also a problem with overflows in the y+(-x) part of your solution (second step).
Now if you're allowed to use other types than int, we can solve both of these problems by casting the values to long long before the conversion, assuming that it's a 64-bit type, so that (~x+1) would return the expected result -x and y+(-x) would not cause any overflows. Then, obviously, we will have to change the >>31 bit to >>63.
The end solution is as follows:
static bool isGreater(int x, int y) {
long long llx = x;
long long lly = y;
long long result = ((lly+(~llx+1))>>63)&1;
return result;
}
It's feasible to test it with some corner-cases, such as x == INT_MIN, x == 0 and x == INT_MAX:
int main(void) {
int x = INT_MIN;
for (long long y = INT_MIN; y <= INT_MAX; ++y) {
assert(isGreater(x, y) == (x > y));
}
x = INT_MAX;
for (long long y = INT_MIN; y <= INT_MAX; ++y) {
assert(isGreater(x, y) == (x > y));
}
x = 0;
for (long long y = INT_MIN; y <= INT_MAX; ++y) {
assert(isGreater(x, y) == (x > y));
}
}
This was successful on my particular machine with my particular compiler. The testing took 163 seconds.
But again, this depends on being able to use other types than int (but then again with more work you could emulate long long with int).
This whole thing could be more portable if you used int32_t and int64_t instead of int and long long, accordingly. However, it still would not be portable:
ISO/IEC 9899:2011 ยง6.5.7 Bitwise shift operators
5 The result of E1 >> E2is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

2's Complement Bitwise Subtraction, Accounting for Zero Case

[Part of a HW question]
Assume 2's complement, 32bit word-length. Only signed int and constants 0 through 0xFF allowed. I've been asked to implement a logical right shift by "n" bits (0 <= n <= 31) using ONLY the operators:
! ~ & ^ | + << >>
I figured I could store and clear the sign bit, perform the shift, and replace the stored sign bit in its new location.
I would like to implement the operation "31 - n" (w/out using the "-" operator) to find the appropriate location for the stored sign bit post shift.
If n were positive, I could use the expression: "31 + (~n + 1)", but I don't believe this will work in the case when n = 0.
Here's what I have so far:
int logicalShift(int x, int n) {
/* Store & clear sign bit, perform shift, and replace stored sign bit
in new location */
int bit = (x >> 31) & 1; // Store most significant bit
x &= ~(1 << 31); // Clear most significant bit
x = x >> n; // Shift by n
x &= ~((~bit) << (31 - n)); // Replace MSbit in new location
return x;
}
Any help and/or hints are appreciated.
[EDIT: Solved]
Thanks to everyone for the help. ~n + 1 works to negate n in this situation, including for the case n = 0 (where it returns 0 as desired). Functional code is below (by no means the most elegant solution). Utility operations borrowed from: How do you set, clear, and toggle a single bit?
int logicalShift(int x, int n) {
/* Store & clear sign bit, perform shift, and replace stored sign bit
in new location */
int bit = (x >> 31) & 1; // Store most significant bit
x &= ~(1 << 31); // Clear most significant bit
x = x >> n; // Shift by n
x ^= ((~bit + 1) ^ x) & (1 << (31 + (~n + 1))); // Replace MSbit in new location
return x;
}
A simple solution is
int logicalShift(int x, int n) {
return (x >> n) ^ (((x & 0x80000000) >> n) << 1);
}
Sadly, using the constant 0x80000000 is forbidden. We could calculate it as 1 << 31 (ignoring undefined behavior in C) or, to save on instruction, calculate 31 - n as n ^ 31 and then use the following somewhat more contrived method:
int logicalShift(int x, int n) {
int b = 1 << (n ^ 31);
return b ^ ((x >> n) + b);
}

In c binary, testing to see if a number is in range

This is part of a puzzle that I can't figure out. The function takes in three inputs. The first is an int, the second is the lower bound and the third is the upper bound. I need to test to see if that first number is within the lower and upper bound inclusive.
If it is in range then return 1, else return 0.
The catch is that I can only use
! ~ & ^ | + << >>
operations and only a combination of 20 of them.. Also, only int variables may be used, and no if statements, loops or function calls.
Range(int x, int lower, int upper){
//... some code here
return retVal;
}
Obviously I understand the logic here. If((x >= lower) && (x <= upper)) return 1;
The only problem is that I can't use if statements, <, >, ==, or &&.
You can make the comparison predicate x < y (returning -1 if true, 0 if false) like this: (see Hacker's Delight, Chapter 2, sub-chapter Comparison Predicates)
((x - y) ^ ((x ^ y) & ((x - y) ^ x))) >> 31;
You didn't list subtraction, but you can emulate x - y with ~(~x + y)
Using two of these predicates, make 1 & ~((x < lower) | (upper < x))
This obviously assumes 2's complement negatives and 32 bit integers with wrapping on overflow. So this is not portable, but that's the norm with this kind of trick.
As requested, that makes the total thing:
int in_range(int x, int lower, int upper)
{
int p = ((x - lower) ^ ((x ^ lower) & ((x - lower) ^ x))) >> 31;
int q = ((upper - x) ^ ((upper ^ x) & ((upper - x) ^ upper))) >> 31;
return 1 & ~(p | q);
}
It still has the subtractions, they're trivial to replace if you really want.
It's possible to make it a tiny tiny bit shorter by using the >= and <= predicates (which can also be found in Hacker's Delight).
Here's my website saying it's correct.
And here's a way that uses less operations, keeping in mind we can't use subtraction:
int p = (x | ~upper) & ((x ^ upper) | (~upper + x));
int q = (lower | ~x) & ((lower ^ x) | (~x + lower));
return 1 & ((p & q) >> 31);
It uses the <= predicate from HD, which looks like (x | ~y) & ((x ^ y) | ~(y - x)) in its pure form.
And here's my website saying it's correct.
Here is a humble solution
int foo(int num, int upp, int low){
return (~((~(upp + ~num + 1)) ^ (~(num + ~low + 1))) >> 31) & 1;
}
do this. i'll tell the logic that can be used.
a=~x+1 //gives -x
b=lower+a //lower-x
c=~upper+1 //gives -upper
d=x+c //x-upper
b=b&0x80000000; //get the msb which is 1 if -ve number
d=d&0x80000000;
return ((b&d)|(!(x^lower))|(!(x^upper))); //& results in +ve only if both b & d are +ve
I'm liking these puzzles you have! For this you will want to have something like,
Ok to be abstract on this one, you will want to have 2 variables.
The first variable (lets call it blarg) you need to set the upper bound and add the flipped x.
Now you will want to add one to blarg and flip it.
Your second variable (lets call it hold) will add the x to the flipped lower bound; After that add 1 to hold and flip it too.
set blarg = to the blarg plus hold;
shift blarg over 31 to the the right.
and AND it with 1.
Should be what you are looking for.

Tell if a 32 bit signed int is a power of 2

I need to determine if a signed 32 bit number is a power of two. So far I know the first thing to do is check if its negative since negative numbers cannot be powers of 2.
Then I need to see if the next numbers are valid etc... SO I was able to write it like this:
// Return 1 if x is a power of 2, and return 0 otherwise.
int func(int x)
{
return ((x != 0) && ((x & (~x + 1)) == x));
}
But for my assignment I can only use 20 of these operators:
! ~ & ^ | + << >>
and NO equality statements or loops or casting or language constructs.
So I am trying to convert the equality parts and I know that !(a^b) is the same as a == b but I cant seem to figure it out completely. Any ideas on how to covert that to the allowed operators?
Tim's comment ashamed me. Let me try to help you to find the answer by yourself.
What does it mean that x is power of 2 in terms of bit manipulation? It means that there is only one bit set to 1. How can we do such a trick, that will turn that bit to 0 and some other possibly to 1? So that & will give 0? In single expression? If you find out - you win.
Try these ideas:
~!!x+1 gives a mask: 0 if x==0 and -1 if x!=0.
(x&(~x+1))^x gives 0 if x has at most 1 bit set and nonzero otherwise, except when ~x is INT_MIN, in which case the result is undefined... You could perhaps split it into multiple parts with bitshifts to avoid this but then I think you'll exceed the operation limit.
You also want to check the sign bit, since negative values are not powers of two...
BTW, it sounds like your instructor is unaware that signed overflow is UB in C. He should be writing these problems for unsigned integers. Even if you want to treat the value semantically as if it were signed, you need unsigned arithmetic to do meaningful bitwise operations like this.
First, in your solution, it should be
return ((x > 0) && ((x & (~x + 1)) == x));
since negative numbers cannot be the power of 2.
According to your requirement, we need to convert ">", "&&", "==" into permitted operators.
First think of ">", an integer>0 when its sign bit is 1 and it is not 0; so we consider
~(x >> 31) & (x & ~0)
this expression above will return a non zero number if x is non-positive. Notice that ~0 = -1, which is 0x11111111. We use x & ~0 to check if this integer is all 0 at each digit.
Secondly we consider "&&". AND is pretty straight forward -- we only need to get 0x01 & 0x01 to return 1. So here we need to add (!!) in front of our first answer to change it to 0x01 if it returns a nonzero number.
Finally, we consider "==". To test equity of A and B we only need to do
!(A ^ B)
So finally we have
return (!!(~(x >> 31) & (x & ~0))) & (!((x&(~x+1)) ^ x))
It seems that it's a homework problem. Please don't simply copy and paste. My answer is kind of awkward, it might be improved.
Think about this... any power of 2 minus 1 is a string of 0s followed by a string of 1s. You can implement minus one by x + ~0. Think about where the string of 1s starts with relation to the single 1 that would be in a power of 2.
int ispower2(int x)
{
int ispositive= ! ( (x>>31) ^ 0) & !!(x^0);
int temp= !((x & ~x+1) ^ x);
return temp & ispositive;
}
It is interesting and efficient to use bitwise operators in C to solve some problems. In this question, we need to deal with two checks:
the sign check. If negative, return 0; otherwise return 1;
! (x >> 31 & ox1) & !(!x)
/* This op. extracts the sign bit in x. However, the >> in this case will be arithmetic. That means there will be all 1 before the last bit(LSB). For negative int, it is oxFFFFFFFF(-); otherwise, oxFFFFFFFE(+). The AND ox1 op. corrects the >> to ox1(-) or ox0(+). The Logical ! turns ox1(-) and ox0 (+) into 0 or 1,respectively. The !(!x) makes sure 0 is not power(2)*/
the isPower(2) check. If yes, return 1; otherwise 0.
!( x & (~x + ox1) ^ x )
/* This op. does the isPower(2) check. The x & (~x + ox1) returns x, if and only if x is power(2). For example: x = ox2 and ~x + ox1 = oxFFFFFFFE. x & (~x + ox1) = ox2; if x = ox5 and ~x + ox1 = oxFFFFFFFB. x & (~x + ox1) = ox1. Therefore, ox2 ^ ox2 = 0; but ox5 ^ ox1 = ox4. The ! op turn 0 and others into 1 and 0, respectively.*/
The last AND op. between 1 and 2 checks will generate the result of isPower(2) function.

Resources