Bit shift issue - java

Given the Following code:
public class Something {
public static void main(String[] args) {
int num = 1;
num <<= 32;
System.out.println(num);
num = 1;
for (int i = 0 ; i < 32; i++)
num <<= 1;
System.out.println(num);
}
}
The first output (from num <<= 32) is 1.
and the second output (from the for loop) is 0.
I dont get it.. it looks the same to me..
both ways shift the "1" digit (lsb) 32 times and the results are different.
Can anyone explain?
Thanks in advance.

Can anyone explain?
Absolutely. Basically, shift operations on int have the right operand masked to get a value in the range [0, 31]. Shift operations on long have it masked to get a value in the range [0, 63].
So:
num <<= 32;
is equivalent to:
num <<= 0;
From section 15.19 of the JLS:
If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

For bit shift operators on int, only the 5 lowest order bits are used. So << 32 does nothing; it's equivalent to << 0, because the last 5 bits of 32 are 0. But the << 1 operations in the loop each perform as expected.

Related

Understanding how bit-shifting works with Negative Shift Values in Java

I am writing a simple program to determine unique characters in a string. I can do this an easier, less efficient way using an Array, but I am trying to implement it using a bit vector. I am able to get correct output fine but I am unsure about why I get the correct output.
My code:
class Main {
public static void main(String args[]) {
System.out.println(isUniqueChars("Robert"));
}
public static boolean isUniqueChars(String str) {
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
System.out.println("Val: " + val); //Val = -15 First Iteration
System.out.print("1 << val: "); //Equals 131072
System.out.println(1 << val);
if ((checker & (1 << val)) > 0) {
return false;
}
System.out.print("Checker: ");
checker = checker | (1 << val);
System.out.println(checker); //Equals 131072
System.out.println();
}
return true;
}
}
I am trying to figure out why 1 << -15 yields 131072. I have searched the internet and have watched a couple of tutorials on shift operators but none of them explain negative shift values.
From the JLS:
If the promoted type of the left-hand operand is int, then only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.
If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x3f (0b111111). The shift distance actually used is therefore always in the range 0 to 63, inclusive.
The constant 1 is an int, so the -15, which is 0xfffffff1 is masked to 0x00000011 indicating a left shift of 17 bits, which is exactly 131072.
One way of looking at it is the bits are shifted in a positive modulo 32 fashion. So what positive number between 0 and 32 is congruent to -15 mod 32? By adding 32 to -15 you get 17. So it's the same as shifting by 17. In fact shifting -15 + k*32 where k is an integer will shift the same amount of bits as shown below.
int k = 4;
int v = 1;
for (int i = -15+(32*-k); i < -15+(32*k); i+= 32) {
int res = v << i;
System.out.printf("1 << %4d == %d%n", i, res );
}
prints
1 << -143 == 131072
1 << -111 == 131072
1 << -79 == 131072
1 << -47 == 131072
1 << -15 == 131072
1 << 17 == 131072
1 << 49 == 131072
1 << 81 == 131072
This also means you can't clear an int by << 32. You need to left shift 31 and then left shift 1. Or more generally, left shift by k and then left shift by 32-k where 1 <= k < 32.
int k = 98;
System.out.println(k<<32); // really shifts by 0
System.out.println((k<<31)<<1));
Prints
98
0
The same rules apply to long with 32 being replaced by 64.

how many arithmetic operation can be made at right side of a variable

for(int i = 1; i <= 5; i++) {
for(int j = 1; j <= i; j++) {
int a = i + j*2;
System.out.print(a);
}
}
when run the above code I am getting output as
3
46
579
681012
79111315
I am not able to understand why it is printing first row as 3, i+j*2 =4 as per the logic.
I am not able to understand why it is printing first row as 3, i+j*2 =4 as per the logic.
Precedence. Multiplication takes precedence over addition, so on the first call, i+j*2 is 1+1*2 which is 1+(1*2) which is 1+2 which is 3.
The precedence of basic operations can be remembered with PEMDAS or BODMAS (the "MD" and "AS" have the same precedence, so I've shown them on a single line here):
P Parentheses / Brackets B
E Exponenentiation / Orders1 O
MD Multiplication & Division DM
AS Addition and Subtraction AS
1 Powers (2^5), square roots, etc.
The Java site has a page on operator precedence, which has this table:
postfix expr++ expr--
unary ++expr --expr +expr -expr ~ !
multiplicative * / %
additive + -
shift << >> >>>
relational < > <= >= instanceof
equality == !=
bitwise AND &
bitwise exclusive OR ^
bitwise inclusive OR |
logical AND &&
logical OR ||
ternary1 ? :
assignment = += -= *= /= %= &= ^= |= <<= >>= >>>=
1 They mean the conditional operator, which is a ternary operator (an operator accepting three operands) and as it happens, the only one Java has.
Multiplication (*) has arithmetic precedence over addition (+). In the first iteration, i and j are both 1. The first thing to be calculated is j*2, i.e., 1*2=2. Then we add i and the previously calculated product and get 1+2=3.

What does '<< ' mean ? And what this code mean?

I don't understand what is this doCalculatePi means or does, in the following example:
public static double doCalculatePi(final int sliceNr) {
final int from = sliceNr * 10;
final int to = from + 10;
final int c = (to << 1) + 1;
double acc = 0;
for (int a = 4 - ((from & 1) << 3), b = (from << 1) + 1; b < c; a = -a, b += 2) {
acc += ((double) a) / b;
}
return acc;
}
public static void main(String args[]){
System.out.println(doCalculatePi(1));
System.out.println(doCalculatePi(2));
System.out.println(doCalculatePi(3));
System.out.println(doCalculatePi(4));
System.out.println(doCalculatePi(10));
System.out.println(doCalculatePi(100));
}
I have printed the values to understand what the results are but I still have no clue what this code calculates. The conditions inside the loop are not clear.
<< means left shift operation, which shifts the left-hand operand left by the number of bits specified by the right-hand operand (See oracle docs).
Say, you have a decimal value, 5 which binary representation is 101
Now for simplicity, consider,
byte a = (byte)0x05;
Hence, the bit representation of a will be,
a = 00000101 // 1 byte is 8 bit
Now if you left shift a by 2, then a will be
a << 2
a = 00010100 //shifted place filled with zero/s
So, you may now understand that, left shift a by 3 means
a << 3
a = 00101000
For better understanding you need to study Bitwise operation.
Note, you are using int instead of byte, and by default, the int data type is a 32-bit signed integer (reference here), so you have to consider,
int a = 5;
in binary
a << 3
a = 00000000 00000000 00000000 00101000 // total 32 bit
My guess is that it approximates PI with
PI = doCalculatePi(0)+doCalculatePi(1)+doCalculatePi(2)+...
Just a guess.
Trying this
double d = 0;
for(int k = 0; k<1000; k++) {
System.out.println(d += doCalculatePi(k));
}
gives me
3.0418396189294032
3.09162380666784
3.1082685666989476
[...]
3.1414924531892394
3.14149255348994
3.1414926535900394
<< is the Bitshift operator.
Basically, every number is represented as a series of binary digits (0's and 1's), and you're shifting each of those digits to the left by however many places you indicate. So for example, 15 is 00001111 and 15 << 1 is 00011110 (or 30), while 15 << 2 is (00111100) which is 60.
There's some special handling that comes into play when you get to the sign bit, but you should get the point.

Java: shift negative number

As far as I understand, the result of shifting a positive integer to the left by 1 is the same as multiply it by two.(if it doesn't overflow)
What will happen to a negative integer?
Is x << 1 always equal to x * 2 if it doesn't overflow?
I tried:
int num = -1;
for (int i= 0; i < 32; i++){
System.out.println(num << i);
}
It prints
-1
-2
-4
-8
-16
-32
-64
-128
-256
-512
-1024
-2048
-4096
-8192
-16384
-32768
-65536
-131072
-262144
-524288
-1048576
-2097152
-4194304
-8388608
-16777216
-33554432
-67108864
-134217728
-268435456
-536870912
-1073741824
-2147483648
Yes, bit-shifting to the left by 1 is always equivalent to multiplying by 2 (except for overflow). The JLS, Section 15.19, even says so:
The value of n << s is n left-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.
I think the JLS states "even if overflow occurs" because it's equivalent to the multiply operation which may overflow also.
It is a bit-shift, you should look at what's going on with bits: -1 is 0xFFFFFFFF, after 1 bit shift to left we will get 0xFFFFFFFE it is -2, etc

How to find most significant bit (MSB)

I want to know which value the first bit of a byte has.
For example:
I have byte m = (byte) 0x8C;
How could I know if the first bit is an 1 or a 0 ?
Can anyone help me out ?
It depends what you mean by "first bit". If you mean "most significant bit" you can use:
// 0 or 1
int msb = (m & 0xff) >> 7;
Or if you don't mind the values being 0x80 or 0, just use:
// 0 or 0x80
int msb = m & 0x80;
Or in fact, as a boolean:
// Uses the fact that byte is signed using 2s complement
// True or false
boolean msb = m < 0;
If you mean the least significant bit, you can just use:
// 0 or 1
int lsb = m & 1;
If the first bit is the lowest bit (ie bit 0), then
if((m & 1) >0) ...
should do it.
In general,
if ((m & (1<<N)) > 0) ...
will give you whether or not bit N is set.
If, however, you meant the highest bit (bit 7), then use N=7.
Assuming you mean leftmost bit, bitwise and it with 0x80 and check if it is zero nor not:
public boolean isFirstBitSet(byte b) {
System.out.println((b & (byte)0x80));
return (b & (byte)0x80) < 0;
}
If you mean lowest order bit you will need to and with 0x01 and check a different condition:
public boolean isFirstBitSet(byte b) {
System.out.println((b & (byte)0x01));
return (b & (byte)0x80) > 0;
}
Use the bitwise and operator.
public class BitExample {
public static void main(String args[]) throws Exception {
byte m = (byte)0x8C;
System.out.println("The first bit is " + (m & (byte)0x01));
m = (byte)0xFF;
System.out.println("The first bit is " + (m & (byte)0x01));
}
}
// output is...
The first bit is 0
The first bit is 1
Its a bit of a hack but you can use
if(x >> -1 != 0) // top bit set.
This works for byte, short, int, long data types.
However for most types the simplest approach is to compare with 0
if (x < 0) // top bit set.
This works for byte, short, int, long, float, or double
(Ignoring negative zero and negative NaN, most people do ;)
For char type you need to know the number of bits. ;)
if (ch >>> 15 != 0) // top bit set.
This code gives you msb(most significant bit)/biggest number which is a
power of 2 and less than any given number.
class msb{
void main(){
int n=155;//let 110001010
int l=(Integer.toBinaryString(n)).length();//9
String w="0"+Integer.toBinaryString(i).substring(1);//010001010
i=Integer.parseInt(w,2);
System.out.println(n^i);//110001010^010001010=100000000
}
}

Categories

Resources