Right shift operator in java - java

public class Operator {
public static void main(String[] args) {
byte a = 5;
int b = 10;
int c = a >> 2 + b >> 2;
System.out.print(c); //prints 0
}
}
when 5 right shifted with 2 bits is 1 and 10 right shifted with 2 bits is 2 then adding the values will be 3 right? How come it prints 0 I am not able to understand even with debugging.

This table provided in JavaDocs will help you understand Operator Precedence in Java
additive + - /\ High Precedence
||
shift << >> >>> || Lower Precedence
So your expression will be
a >> 2 + b >> 2;
a >> 12 >> 2; // hence 0

It's all about operator precedence. Addition operator has more precedence over shift operators.
Your expression is same as:
int c = a >> (2 + b) >> 2;

Is this what you want?
int c = ((a >> 2) + b) >> 2;
You were shifting to the right by whatever is 2+b. I assume you wanted to shift 5 by 2 positions, right?
b000101 >> 2 == b0001øø
| |___________________|_|
| |
|_____________________|
i.e. the leftmost bit shifts to the right by 2 positions and right most bit does as well (but is has no more valid positions left on its right side so it simply disappears) and the number becomes what's left - in this case '1'. If you shift number 5 by 12 positions you will get zero as 5 has less than 12 positions in binary form. In case of '5' you can shift by 2 positions at most if you want to preserve non-zero value.

Related

Bitwise Operator | and + the same?

Looking at |, it is described as a bitwise operator OR.
So, in this code example:
private int getColorRGB(int color) { // 255255255 would be white, 000255000 green, etc.
if (color < 0) return -1;
int r = color / 1000000 % 1000;
int g = color / 1000 % 1000;
int b = color % 1000;
if (r > 255 || g > 255 || b > 255) throw new IllegalArgumentException("RGB values cannot exceed 255.");
return (r >> 16) | (g >> 8) | b; // POINT OF INTEREST
}
I can replace the 2 | at the line marked with POINT OF INTEREST with +, and I still get the same output.
The method takes an int rrrgggbbb, so 255 would be blue, 200200200 would be light gray, etc.
So, my question is; what is the difference between the two
a = 2; // binary 0x10
b = 2; // binary 0x10
c = a + b; // c = 4
c = a | b; // c = 2
| is a bit operation and it doesn't equals +
Sometimes it gives the same result: 2+1 and 2|1 for example; but it isn't a rule
| takes the bitwise OR means takes the greater corresponding bit of the two numbers while + takes the addition of the two corresponding bits and takes further carries which means 1+1 gives us as 10 while 1|1 will stops only to 1. | will never cause out of range if larger argument is in range while + can have out or range if if sum of both causes a number out of range.
If in two numbers, corresponding bits are different, then only in that case | acts as + because during summation, carries never produces.
Remember | and + are 2 different operators. That being said, sometimes they can have the same result, like 1*1 and 1/1. While they have the same result, they do not go through the same process.

Add two numbers without using + or any arithmetic operators

Here is the reference implementation I got, the confusion is, I think there is no need for recursion. I post both reference code and my thought below here, for the difference see line 5.
Any insights are appreciated. Please feel free to correct me if I am wrong.
Reference implementation:
1 int add_no_arithm(int a, int b) {
2 if (b == 0) return a;
3 int sum = a ^ b; // add without carrying
4 int carry = (a & b) << 1; // carry, but don’t add
5 return add_no_arithm(sum, carry); // recurse
6 }
Another implementation in my thought,
1 int add_no_arithm(int a, int b) {
2 if (b == 0) return a;
3 int sum = a ^ b; // add without carrying
4 int carry = (a & b) << 1; // carry, but don’t add
5 return sum ^ carry;
6 }
BTW, tried 8+8 in Python - worked for me:
Is the recursion needed?
a = 8
b = 8
sum = a ^ b
carry = (a & b) << 1
print(sum^carry) # 16
The second approach doesn't work with 1 + 3.
Here are the steps
a == 01
b == 11
sum = a^b == 10
carry = (a&b) << 1 == 10
sum ^ carry == 00 // wrong answer! 1 + 3 == 4
Just doing ^ at the last step is not enough, as there may be a carry in that sum.
The question is, whether recursive is needed?
Yes, it is. You can see this for yourself by experimenting with other numbers, instead of just 8 + 8. For example, try 21 and 15, without recursion this gives output of 26.
The bitwise XOR operator ^ is only equivalent to the addition operator + if there is no binary carrying in the sums. If there is binary carrying, then they are not equivalent. For example, 8 + 7 equals 8 ^ 7 equals 15, but 8 + 8 is 16 while 8 ^ 8 is 0.
Even if you have calculated the sum-no-carry and the carry-no-sum correctly, what if those two numbers, when added, would produce a binary carry? Then your ^ operator at the end would be incorrect. Without the + operator, the only option I see is to recurse, to add those numbers. This will recur until one of the numbers is 0.
Example:
add(no_arithm(18, 6))
sum = a^b 18 ^ 6 is 20.
carry = (a & b) << 1 18 & 6 is 2, bit shift left 1 is 4.
return sum ^ carry 20 ^ 4 is 16, incorrect (18 + 6 = 24).
Will this work?
import java.util.*;
public class Solution {
public static int sumOfTwoNumbers(int a, int b) {
if (b<0){
for(int j = 1; j<=-b;j++)
--a;
}
if(b>0){
for (int i = 1; i <= b; i++){
a++;
}
}
return a;
}

Compare two integers using bit operator

I need to compare two integer using Bit operator.
I faced a problem where I have to compare two integers without using comparison operator.Using bit operator would help.But how?
Lets say
a = 4;
b = 5;
We have to show a is not equal to b.
But,I would like to extend it further ,say,we will show which is greater.Here b is greater..
You need at least comparison to 0 and notionally this is what the CPU does for a comparison. e.g.
Equals can be modelled as ^ as the bits have to be the same to return 0
(a ^ b) == 0
if this was C you could drop the == 0 as this can be implied with
!(a ^ b)
but in Java you can't convert an int to a boolean without at least some comparison.
For comparison you usually do a subtraction, though one which handles overflows.
(long) a - b > 0 // same as a > b
subtraction is the same as adding a negative and negative is the same as ~x+1 so you can do
(long) a + ~ (long) b + 1 > 0
to drop the +1 you can change this to
(long) a + ~ (long) b >= 0 // same as a > b
You could implement + as a series of bit by bit operations with >> << & | and ^ but I wouldn't inflict that on you.
You cannot convert 1 or 0 to bool without a comparison operator like Peter mentioned. It is still possible to get max without a comparison operator.
I'm using bit (1 or 0) instead of int to avoid confusion.
bit msb(x):
return lsb(x >> 31)
bit lsb(x):
return x &1
// returns 1 if x < 0, 0 if x >= 0
bit isNegative(x):
return msb(x)
With these helpers isGreater(a, b) looks like,
// BUG: bug due to overflow when a is -ve and b is +ve
// returns 1 if a > b, 0 if a <= b
bit isGreater_BUG(a, b):
return isNegative(b - a) // possible overflow
We need two helpers functions to detect same and different signs,
// toggles lsb only
bit toggle(x):
return lsb(~x)
// returns 1 if a, b have same signs (0 is considered +ve).
bit isSameSigns(a, b):
return toggle(isDiffSigns(a, b))
// returns 1 if a, b have different signs (0 is considered +ve).
bit isDiffSigns(a, b):
return msb(a ^ b)
So with the overflow issue fix,
// returns 1 if a > b, 0 if a <= b
bit isGreater(a, b):
return
(isSameSigns(a, b) & isNegative(b - a)) |
(isDiffSigns(a, b) & isNegative(b))
Note that isGreater works correctly for inputs 5, 0 and 0, -5 also.
It's trickier to implement isPositive(x) properly as 0 will also be considered positive. So instead of using isPositive(a - b) above, isNegative(b - a) is used as isNegative(x) works correctly for 0.
Now max can be implemented as,
// BUG: returns 0 when a == b instead of a (or b)
// returns a if a > b, b if b > a
int max_BUG(a, b):
return
isGreater(a, b) * a + // returns 0 when a = b
isGreater(b, a) * b //
To fix that, helper isZero(x) is used,
// returns 1 if x is 0, else 0
bit isZero(x):
// x | -x will have msb 1 for a non-zero integer
// and 0 for 0
return toggle(msb(x | -x))
So with the fix when a = b,
// returns 1 if a == b else 0
bit isEqual(a, b):
return isZero(a - b) // or isZero(a ^ b)
int max(a, b):
return
isGreater(a, b) * a + // a > b, so a
isGreater(b, a) * b + // b > a, so b
isEqual(a, b) * a // a = b, so a (or b)
That said, if isPositive(0) returns 1 then max(5, 5) will return 10 instead of 5. So a correct isPositive(x) implementation will be,
// returns 1 if x > 0, 0 if x <= 0
bit isPositive(x):
return isNotZero(x) & toggle(isNegative(x))
// returns 1 if x != 0, else 0
bit isNotZero(x):
return msb(x | -x)
Using binary two’s complement notation
int findMax( int x, int y)
{
int z = x - y;
int i = (z >> 31) & 0x1;
int max = x - i * z;
return max;
}
Reference: Here
a ^ b = c // XOR the inputs
// If a equals b, c is zero. Else c is some other value
c[0] | c[1] ... | c[n] = d // OR the bits
// If c equals zero, d equals zero. Else d equals 1
Note: a,b,c are n-bit integers and d is a bit
The solution in java without using a comparator operator:
int a = 10;
int b = 12;
boolean[] bol = new boolean[] {true};
try {
boolean c = bol[a ^ b];
System.out.println("The two integers are equal!");
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
System.out.println("The two integers are not equal!");
int z = a - b;
int i = (z >> 31) & 0x1;
System.out.println("The bigger integer is " + (a - i * z));
}
I am going to assume you need an integer (0 or 1) because you will need a comparison to get a boolean from integer in java.
Here, is a simple solution that doesn't use comparison but uses subtraction which can actually be done using bitwise operations (but not recommended because it takes a lot of cycles in software).
// For equality,
// 1. Perform r=a^b.
// If they are equal you get all bits 0. Otherwise some bits are 1.
// 2. Cast it to a larger datatype 0 to have an extra bit for sign.
// You will need to clear the high bits because of signed casting.
// You can split it into two parts if you can't cast.
// 3. Perform -r.
// If all bits are 0, you will get 0.
// If some bits are not 0, then you get a negative number.
// 4. Shift right to extract MSB.
// This will give -1 (because of sign extension) for not equal and 0 for equal.
// You can easily convert it to 0 and 1 by adding 1 (I didn't include it in below function).
int equality(int a, int b) {
long r = ((long)(a^b)) ^0xffffffffl;
return (int)(((long)-r) >> 63);
}
// For greater_than,
// 1. Cast a and b to larger datatype to get more bits.
// You can split it into two parts if you can't cast.
// 2. Perform b-a.
// If a>b, then negative number (MSB is 1)
// If a<=b, then positive number or zero (MSB is 0)
// 3. Shift right to extract MSB.
// This will give -1 (because of sign extension) for greater than and 0 for not.
// You can easily convert it to 0 and 1 by negating it (I didn't include it in below function).
int greater_than(int a, int b) {
long r = (long)b-(long)a;
return (int)(r >> 63);
}
Less than is similar to greater but you swap a and b.
Trivia: These comparison functions are actually used in security (Cryptography) because the CPU comparison is not constant-time; aka not secure against timing attacks.

Calculate set bits in character

So I saw this one question on the interwebs that was along the lines of
Write a function that counts the number of bits in a character
Now obviously this confused me (or I wouldn't be here).
My very first thought was "aren't all chars 16 bits by default?" but obviously that has to be wrong because this question exists. I have no idea where to start. Maybe I can get the hex value of a char? Is there an easy way to convert from hex to binary or something? Is this something that can be asked about ANY language (I'm curious about Java here) or does it only matter to like C or something?
Here's another approach if you want to avoid recursion.
public static int bitsSet(char arg) {
int counter = 0;
for (int oneBit = 1; oneBit <= 0x8000; oneBit <<= 1) {
if ((arg & oneBit) > 0) {
counter++;
}
}
return counter;
}
Update
Here's a bit of an explanation. In the loop, oneBit bit-shifts to the left each time, which doubles its value. The <<= operation is a kind of shorthand for oneBit = oneBit << 1. So, the first time through, we have oneBit = 0000000000000001. Then the next time, we have oneBit = 0000000000000010, then oneBit = 0000000000000100, and so on, until we reach the last iteration, when we have oneBit = 1000000000000000 (these are all binary of course).
Now, the value of arg & oneBit will equal oneBit if arg has the matching bit set, or 0 otherwise. So the condition is executing counter++ if it encounters a set bit. By the time the loop has run all 16 times, we've counted all the set bits.
I'm assuming from your title that you're after the number of "set bits" (that is, bits that are equal to one). You can do it like this.
public static int bitsSet(char arg) {
return arg == 0 ? 0 : (arg & 1) + bitsSet((char)( arg >>> 1 ));
}
And yes, all chars in Java are 16 bits.
Update
Here's a bit of an explanation. (arg & 1) will check the rightmost bit of arg and return 0 or 1 depending on whether it is clear or set. So we want to take that 0 or 1, and add it to the number of set bits among the leftmost 15 bits. So to work that out, we shift arg to the right, introducing a zero at the left end. We need >>> rather than >> to make sure that we get a zero at the left end. Then we call bitsSet all over again, with the right-shifted value of arg.
But every time we do that, arg gets smaller, so eventually it's going to reach zero. When that happens, no more bits are set, so we can return 0.
To see the recursion working, take, for example, arg = '%' = 100101. Then we have the following - where all numbers shown are binary -
bitsSet(100101)
= (100101 & 1) + bitsSet(10010))
= (100101 & 1) + (10010 & 1) + bitsSet(1001)
= (100101 & 1) + (10010 & 1) + (1001 & 1) + bitsSet(100)
= (100101 & 1) + (10010 & 1) + (1001 & 1) + (100 & 1) + bitsSet(10)
= (100101 & 1) + (10010 & 1) + (1001 & 1) + (100 & 1) + (10 & 1) + bitsSet(1)
= (100101 & 1) + (10010 & 1) + (1001 & 1) + (100 & 1) + (10 & 1) + (1 & 1) + bitsSet(0)
= 1 + 0 + 1 + 0 + 0 + 1 + 0
= 3
All chars are 1-byte in C, Unicode (TCHAR) char's are 2 bytes.
To count the bits, you do bit shifting. I am not really that good at binary arithmetic personally.
According to Oracle JAVA doc for primitives.
char: The char data type is a single 16-bit Unicode character.

Left bit shift 0 in Java

Consider:
int a = 0;
a |= 1 << a;
System.out.println(a);
It prints "1". Why? I thought left bit shifting 0 by any number of times was still 0. Where's it pulling the 1 from?
The expression 1 << a; will shift the value 1, a number of times.
In other words, you have the value 1:
0000001
Now, you shift the whole thing over 0 bits to the left. You then have:
0000001
You then have:
a |= 1 << a;
Which resolves to:
a = 0000000 | 0000001
Or:
a = 1;
You might have the operands mixed up. If you're trying to shift the value 0 one bit to the left, you'd want:
a |= a << 1;
You are using the operator << in a wrong way.
It must to be:
int a = 0;
a |= a << 1;
System.out.println(a);
You are left shifting the literal 1 by the variable a. The value of variable a is zero. 1<<0 = 1
So you've just got your variables flipped. Try reversing the variables.

Categories