Weird bit shifting behaviour - java

I was attempting the powerset problem with iteration and bit shifting.
There is a particular behaviour I am unable to comprehend.
I would have expected all the 3 statement below to indicate testing if jth bit in i is set.
Why are the results different then?
private static void printSubsetInBit(Integer[] arr) {
for(int i=0;i<(1<<arr.length);i++){
List<Integer> pack=new ArrayList<Integer>();
for(int j=0;j<arr.length;j++){
//if(((i>>j)&1)==1){ -->>>> WORKS
//if((i & ( 1<<j))>0){-->>>> WORKS
if((i & ( 1<<j))==1){ -->>>> DOES NOT WORK
pack.add(arr[j]);
}
}
System.out.println(pack.toString());
}
}

If you left-shift 1 by j and then use it to mask i, you have to compare the result to the result of left-shifting 1 by j, not to 1.
In other words the condition should be
((i & (1 << j)) == (1 << j))
Or just "!= 0" would be fine.

(i & ( 1<<j))==1 is false unless j == 0, because ((1<<j) & 1 == 0) == (j != 0) (*).
This is simply not equivalent to the other expressions.
(*) Well, j % 32 == 0/j % 32 != 0; the second operand is masked.

Related

Converting C statement in to Java (Array[][] != 0)

I'm changing some C code into Java, but I have come across a statement syntax that I have not seen before and I don't know what it means.
for (unsigned int i = 0; i < SIZE; i++)
{
count[2 * SIZE + 1] += grid[i][SIZE - 1 - i] != 0;
}
When adding elements of two arrays, I've never seen '!= 0' come after it. Do you know what this statement is doing? I can't find any reference to this online.
Any help is appreciated.
grid[i][SIZE - 1 - i] != 0 is a boolean expression which (by the C standard) is evaluated to 1 if the expression is true, 0 otherwise.
The same thing can be written as following:
for (unsigned int i = 0; i < SIZE; i++)
{
if ( grid[i][SIZE - 1 - i] != 0)
{
count[2 * SIZE + 1] += 1;
}
}
Unlike in C/C++, in Java, the result of this test is a boolean not an integer (0/1), and you cannot add a boolean so it counts for 0 for false or 1 for true.
I suggest a simple test which avoids to add 0 to count uselessly. So probably faster (well, constant branching could make it slower, has to be benched) & less cryptic (that's a fact), and valid in C, C++ or Java:
if (grid[i][SIZE - 1 - i] != 0)
{
count[2 * SIZE + 1]++;
}
Booleans can be implicitly converted to integers.
It is equivalent to
(grid[i][SIZE - 1 - i] != 0) ? 1 : 0
that is, add 1 if the condition is true and zero otherwise.

What is meaning of expression while(n&3)==0 and n>>=2

I find confused with these expression while(n&3)==0 and n>>=2 . I am not sure when this condition is executed while((n&3)==0) and what happens n>>=2
public int numSquares(int n) {
while ((n & 3) == 0) //n % 4 == 0
n >>= 2;
if ((n & 7) == 7) return 4; //n% 8 == 7
if(is_square(n)) return 1;
int sqrt_n = (int) Math.sqrt(n);
for (int i = 1; i<= sqrt_n; i++){
if (is_square(n-i*i)) return 2;
}
return 3;
}
public boolean is_square(int n){
int temp = (int) Math.sqrt(n);
return temp * temp == n;
}
& is a binary AND operator. 3's representation in binary is 0000..0011. Therefore, the condition
(n & 3) == 0
is true when the last two bits of n are both set to zero. This happens when the number is divisible by 4, as suggested by the n % 4 == 0 comment.
Similarly, (n & 7) == 7 means "the last three bits of n are all set to 1", because the binary representation of 7 is 000..00111. Again, this is equivalent to having the remainder of 7 after dividing by 8, hence the n% 8 == 7 comment.
When you do n>>=2, you shift the number by two bits to the right, with sign extension. In your context it is equivalent to division by four, because the loop stops as soon as n is no longer divisible by four.
(n & 3) == 0 is an overly complex way of saying "n is a multiple of 4".
n>>=2 is an overly complex way of saying "divide n by 4, rounding down to the next lowest integer".
So this loop means "Keep dividing n by 4 until it's no longer a multiple of 4".
& is a bitwise AND
Bitwise operator works on bits in case of AND it return 1 only if both operands are 1, otherwise zero.
Suppose n = 4 in your case then
n & 3 would be 100 & 011 will give you 000 ie 0
>> bitshift operator
n >> 2 would be 100 >> 2 give you 001 ie 1
shifting each bit to the right 2 times.
You can read about the more in Docs

how to get absolute value of a number in java using bit manipulation

I want to implement a function to get the absolute value of a number in java: do nothing if it is positive, if it is negative, convert to positive.
I want to do this only using bit manipulations and no number comparators.
Please help
Well a negation:
-n
Is the same as the two's complement:
~n + 1
The problem is here you only want to negate if the value is < 0. You can find that out by using a logical shift to see if the MSB is set:
n >>> 31
A complement would be the same as an XOR with all 1's, something like (for a 4-bit integer):
~1010 == 1010 ^ 1111
And we can get a mask with the arithmetic right shift:
n >> 31
Absolute value says:
if n is < 0, negate it (take the complement and add 1 to it)
else, do nothing to it
So putting it together we can do the following:
static int abs(int n) {
return (n ^ (n >> 31)) + (n >>> 31);
}
Which computes:
if n is < 0, XOR it with all 1's and add 1 to it
else, XOR it with all 0's and add 0 to it
I'm not sure there's an easy way to do it without the addition. Addition involves any number of carries, even for a simple increment.
For example 2 + 1 has no carry:
10 + 1 == 11
But 47 + 1 has 4 carries:
101111 + 1 == 110000
Doing the add and carry with bitwise/bit shifts would basically just be a loop unroll and pointless.
(Edit!)
Just to be silly, here is an increment and carry:
static int abs(int n) {
int s = n >>> 31;
n ^= n >> 31;
int c;
do {
c = (n & s) << 1;
n ^= s;
} while((s = c) != 0);
return n;
}
The way it works is it flips the first bit, then keeps flipping until it finds a 0. So then the job is just to unroll the loop. The loop body can be represented by a somewhat ridiculous compound one-liner.
static int abs(int n) {
int s = n >>> 31;
n ^= n >> 31;
int c = (n & s) << 1;
c = ((n ^= s) & (s = c)) << 1; // repeat this line 30 more times
n ^= s;
return n;
}
So there's an abs using only bitwise and bit shifts.
These aren't faster than Math.abs. Math.abs just returns n < 0 ? -n : n which is trivial. And actually the loop unroll totally sucks in comparison. Just a curiosity I guess. Here's my benchmark:
Math.abs: 4.627323150634766ns
shift/xor/add abs: 6.729459762573242ns
loop abs: 12.028789520263672ns
unrolled abs: 32.47122764587402ns
bit hacks abs: 6.380939483642578ns
(The bit hacks abs is the non-patented one shown here which is basically the same idea as mine except a little harder to understand.)
you can turn a two's-compliment number positive or negative by taking it's logical negation
i = ~i; // i equals not i
You can use the Math.max() function to always get the positive
public static int abs(int i) {
return Math.max(i,~i);
}
This depends on what type of number you are using. For an int, use
int sign = i >> 31;
This gets the sign bit, which is 0 for positive numbers, and 1 for negative numbers. For other primitive types, replace 31 with the number of bits used for the primitive minus 1.
You can then use that sign in your if statement.
if (sign == 1)
i = ~i + 1;
I think you'll find that this little ditty is what you're looking for:
int abs(int v) {
int mask = v >> Integer.SIZE - 1;
return v + mask ^ mask;
}
It's based on Bit Twiddling Hacks absolute value equation and uses no comparison operations. If you aren't allowed to use addition, then (v ^ mask) - mask is an alternative. The value of this function is fairly questionable; since it's nearly as clear as the implementation of Math.abs and it's only marginally faster (at least on a i7):
v + mask ^ mask: 2.0844380704220384 abs/ns
(v ^ mask) - mask: 2.0819764093030244 abs/ns
Math.abs: 2.2636355843860656 abs/ns
Here's a test that proves that it works over the entire range of integers (the test runs in less than 2 minutes on an i7 processor under Java 7 update 51):
package test;
import org.hamcrest.core.Is;
import org.junit.Assert;
import org.junit.Test;
public class AbsTest {
#Test
public void test() {
long processedCount = 0L;
long numberOfIntegers = 1L << Integer.SIZE; //4294967296L
int value;
for (value = Integer.MIN_VALUE; processedCount < numberOfIntegers; value++) {
Assert.assertEquals((long) abs(value), (long) StrictMath.abs(value));
if (processedCount % 1_000_000L == 0L) {
System.out.print(".");
}
processedCount++;
}
System.out.println();
Assert.assertThat(processedCount, Is.is(numberOfIntegers));
Assert.assertThat(value - 1, Is.is(Integer.MAX_VALUE));
}
private static int abs(int v) {
int mask = v >> Integer.SIZE - 1;
return v + mask ^ mask;
}
}
This problem can be broken down into 2 simple steps:
1.
If >= 0 then just return the number.
2.
If smaller than 0 (ie. negative), then flip the first bit that indicates that the number is negative. This can easily be done with an XOR operation with -1 and the number; Then simply add +1 to deal with the offset (signed integers start at -1 not 0).
public static int absolute(int a) {
if (a >= 0) {
return a;
} else {
return (a ^ -1) + 1;
}
}

Java simplify the syntax

What would be the most terse way in Java to check for the following condition
int m, n;
The condition to check is whether either m or n are negative but both shouldn't be negative. I'm looking for a terse yet simple syntax
(m < 0) ^ (n < 0)
Note that in this context, ^ is the logical XOR operator (yes, I do mean "logical", distinct from "bitwise").
(m ^ n) < 0
Even more filler to make an appropriate length answer.
I'd go for:
(m < 0) != (n < 0)
!= operates the same as ^ for booleans, but I think it's easier to understand and more commonly used.
Basically your test should be - the sign bit (highest order) shound be different.
Here is the test expressed in java;
if ( (x & Integer.MIN_VALUE) != (y & Integer.MIN_VALUE) )
...

Why doesn't this loop terminate?

Here's the sample code:
public static void col (int n)
{
if (n % 2 == 0)
n = n/2 ;
if (n % 2 != 0)
n = ((n*3)+1) ;
System.out.println (n) ;
if (n != 1)
col (n) ;
}
this works just fine until it gets down to 2. then it outputs 2 4 2 4 2 4 2 4 2 4 infinitely. it seems to me that if 2 is entered as n then (n % 2 == 0) is true 2 will be divided by 2 to yeild 1. then 1 will be printed and since (n != 1) is false the loop will terminate.
Why doesn't this happen?
Because when you get to 1, you are multiplying by 3 and adding 1, taking you back to 4.
You need an ELSE in there. I don't know java, but it would look something like:
public static void col (int n)
{
if (n % 2 == 0)
n = n/2 ;
else if (n % 2 != 0)
n = ((n*3)+1) ;
System.out.println (n) ;
if (n != 1)
col (n) ;
}
EDIT: as mentioned in the comments, you can omit the if test after the else:
if (n % 2 == 0)
n = n/2 ;
else
n = ((n*3)+1) ;
I think you'll have to change the 2nd if statement to an else
if (n % 2 == 0) // if the n is even
n = n/2 ;
else // if n is odd
n = ((n*3)+1) ;
The answer to the question can be read directly in the code:
Assume n is 2
(n % 2 == 0) is true therefore n <- 1
(n % 2 != 0) is also true therefore 4 <- n
this warrants a call to function with n = 4, which is then changed to 2 and
"back to square 1"
by replacing the second test by an else, you solve this logic problem, at the cost of possibly causing more recursion (since in the current logic, two operations are sometimes performed in one iteration). Such a fix will also solve a more subtle bug, which is that in the current version not all new values of n are printed out.
Now, for extra credit, prove that not matter the initial value of n, the number of recursions is finite (i.e. the sequence converges to 1). ;-)
Use if/then/else. Your logic is wrong.
when the input is 2:
if (n % 2 == 0) //true
n = n/2; //n = 1
if (n % 2 != 0) //true
n = ((n*3)+1); //n = 4
System.out.println (n); //prints 4
if (n != 1) //true
col (n); //call col(4)
Does it work if you change it to this?
if (n % 2 == 0)
n = n/2 ;
else if (n % 2 != 0)
n = ((n*3)+1) ;
It looks like you're getting 2, dividing by 2 to get 1, then checking to see if 1/2 has a remainder (it does), and multiplying it by 3 and adding 1, to get 4....
if (n % 2 != 0)
n = ((n*3)+1) ;
this code is again implemented whenever u get 1.
therefore the recursive function will be called repeatedly hence leading to an infinite rec calling and code will never terminate.
in addition to an else if to govern the condition that n is odd that same line also needs & n != 1 to be added to it within the conditional. So this:
else if (n % 2 != 0 & n != 1)

Categories