Shift Operator in Java [duplicate] - java

This question already has answers here:
Why does Java mask shift operands with 0x1F?
(2 answers)
Closed 9 years ago.
How does the shift operator << work when the value of the shift bits is greater than the total number of bits for the datatype?
For example,
int i = 2;
int j = i<<34;
System.out.println(j);
The size of an integer is 32 bits, however we are shifting 34 bits. How does this work?

I'm not sure the source on this, but according to WikiPedia (emphasis mine):
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 & with the mask value 0x1f (0b11111).[4]
The shift distance actually used is therefore always in the range 0 to
31, inclusive.
Edit: It looks like the WikiPedia entry basically lifted the information straight out of the Java Specification.

When you shift an integer with the << or >> operator and the shift distance is greater than or equal to 32, you take the shift distance mod 32 (in other words, you mask off all but the low order 5 bits of the shift distance).
This can be very counterintuitive. For example (i >> 32) == i, for every integer i. You might expect it to shift the entire number off to the right, returning 0 for positive inputs and -1 for negative inputs, but it doesn't; it simply returns i, because
(i << (32 & 0x1f)) == (i << 0) == i.
Getting back to your original problem, (i << 33) == (i << (33 & 0x1f))
== (i << 1). You can do the whole thing in binary if you like. 270 in binary is : 0000 0000 0000 0000 0000 0001 0000 1110 Shifting right by 1,
you get: 0000 0000 0000 0000 0000 0000 1000 0111 which is 135.
But a better way to do this problem in your head is to dispense with the binary entirely.
The value of i >> s is floor(i / 2<sup>s</sup>) (where s has already been masked off so it's less than 32). So, 270 << 1 = floor(270/2) = 135.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19

If you try 1 << 34, you end up with 4. The runtime basically has an implicit mod NUMBER_OF_BITS on the right-hand operand of the shift. In the previous example, it's 1 << (34 % 32), which becomes 1 << 2, which is 4.

Related

Why doesn't (52 & (1 << 37)) return 0?

I'm trying to make an algorithm that given an integer, spits out the string representation of its binary form.
Now, I'm basically comparing a mask to see where to append the 1/0 bits. This worked fine until slightly larger numbers appeared, e.g.: (52 & (1 << 37)) which, if I understood the bitshift operator correctly (apparently I didn't) should return 0, because (1 << 37) = 1 and 37 * 0's. Now last time I checked, there are no 1's in the 38th place of the decimal 52 in binary format, so why does this return 32?
This entire expression is performed using 32 bit numbers because all of the operands are int values.
So therefore 1 << 37 is not a "one" followed by 37 "zero" bits.
In fact, JLS 15.9 says that the shift count is masked with 0x1f (for the 32 bit shift operators). Thus 1 << 37 actually means the same thing as 1 << 5; i.e. a "one" followed by 5 "zero" bits.
If you want to use 64 bit integers in the shift expression, the first operand must be a long; i.e. (52 & (1L << 37)).
In java, Integer is a 32 bit representation (irrespective of 32 or 64 bit architecture).
The following will give a 0 as expected while long is used(37 < 64):
(52 & (1L << 37))
With long, the same problem will arise for a shift greater than 63 (more specifically greater than (1 << 63) - 1))
Now considering why the answer is 32 with integer:
1 << 31 == Integer.MIN_VALUE
(1 << 32) - 1 == 0
1 << 32 == 1 == 2^(32 - 32) == 2^0
1 << 33 == 2 == 2^(33 - 32) == 2^1
1 << 34 == 4 == 2^(34 - 32) == 2^2
1 << 37 == 32 == 2^(37 - 32) == 2^5
Because the Java Language Specification says about left-shifting (an older one, but these things do not change much) that
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.
So when operating on 32-bit ints, the << 37 in your code becomes << 5, and 52 & (1 << 5) is really 32.

What does the & symbol mean here and whats going on here?

I was going through a java file and saw this block of code and can't really understand what's happening here. What does the & symbol means here and when I run this, I get the values 2 and 8 respectively.
package com.company;
public class Question_2 {
public static void main(String[] args) {
int mask = 0x000F;
int value = 0x2222;
int f = 90;
int h = 9;
System.out.println(value & mask);
System.out.println(f & h);
}
}
This is The output I get:
2
8
& is a bit wise operation
& is 1 if both bit at the same position is 1 otherwise 0
Also, to perform this operation, your operands will be converted to base 2
90 = 0101 1010 in base 2
09 = 0000 1001 in base 2
_________
0000 1000 which is 8 convert to decimal
000f in hexadecimal = 0000 0000 0000 1111
2222 in hexadecimal = 0010 0010 0010 0010
using & on this is 0000 0000 0000 0010 which is 2 convert to decimal
That is how basic & operator works.
& refers to Bitwise AND operation.
the mask variable used to enable specific bit and disable the others.
in this code,
System.out.println(value & mask);
the mask keeps the first (from right to left) 4 bits and unsets the others, so always the value of the bitwise AND between the mask variable and any value will be less than 15 because 0x000F -> 0000 0000 0000 1111
mathematically: since the mask is 0x000F if the value of & between the mask and any value is zero then the number is dividable by 16 otherwise it's not dividable by 16
& is the bitwise AND operation.
System.out.println(value & mask);
outputs the hex representation of bitwise ANS.
System.out.println(f & h);
outputs the decimal representation of the bitwise AND.
& is smart enough to return the result of the same representation as it's arguments.
& is used as a relational operator to check a conditional statement just like && operator.
but there is a small change in how & takes care of conditional statement. && would first check the first data, if its true then it checks the next one and son on.. but in case of single & character, it just evaluate all conditions even if previous one is a failed one. Thus, any change in the data values due to the conditions will only be reflected in this case.
& can also be used as bitwise operator
println(f & h ) ->
01011010
& 00001001
00001000 -> 8 in decimal

Convert 64bit data to signed long value

I have something like this:
byte[0] = 0001 0100 0011 0100 (dec value: 5172)
byte[1] = 0000 0000 0111 1100 (dec value: 124)
byte[2] = 0000 0000 0000 0000 (dec value: 0)
byte[3] = 0000 0000 0000 0000 (dec value: 0)
I would like to combine them and make one long value in Java. How to do that?
Can it be converted on this way?
result = 0 + (0 x 2^16) + (0 x 2^16) + (124 x 2^32) + (5127 x 2^48)
ie.
result = byte[3] + (byte[2] x 2^16) + (byte[1] x 2^32) + (byte[0] x 2^48)
Edit: Let me try to explain better. When I open tool ModScan32 and connect to my device I see some registers. In this tool there are different kind of options how to show data. One of them are to represent them as binary or decimal. When I choose binary or decimal I get values as they are in my example above. When I read this data with my software I get exactly the same (converted values) in the decimal. Now my question is if it is necessary to hold data in 4 16 bit registers and i know their decimal values what is the proper way to combine those values from registers and get real value?
Your idea is basically OK. There are a few things to be aware of.
I believe the result you are after in your case is 0001010000110100000000000111110000000000000000000000000000000000.
Here’s an attempt that does not work:
int[] registers = { 5172, 124, 0, 0 };
long result = registers[0] << 48 | registers[1] << 32 | registers[2] << 16 | registers[3];
System.out.println(Long.toBinaryString(result));
<< 48 means shift 48 bits to the left, that should be good enough, right? | is a bitwise logical or, it fills the 1 bits from either operand into the same bit posistion of the result. You could use + instead if you preferred.
This prints:
10100001101000000000001111100
We only have the first 32 bits of the result, that’s not good enough. When trying to read it, note that Long.toBinaryString() does not include leading zeroes. Just imagine 3 zeroes in front of the number.
But what went worng? Where did the last 32 bits go? Even when they were all zeroes. The problem is that we are doing the calculation in ints, they are 32 bits, not 64. EDIT: My previous explanation was not entirely correct on this point. The truth is: When doing << on an int, only the last 5 bits of the right operand are considered, so since 48 is 110000 in binary, only 10000 is used, so the shift is the same as << 16. Similarly << 32 is the same as << 0, no shift at all. So registers[0] and [1] have ended up in the wrong bit posistion. The solution is easy when you know it: we need to convert to long before doing the calculation. Now the last 6 bits of the right operand are used, so 48 and 32 are understood as 48 and 32:
long result = ((long) registers[0]) << 48 | ((long) registers[1]) << 32 | registers[2] << 16 | registers[3];
This time we get
1010000110100000000000111110000000000000000000000000000000000
Again, imagine 3 zero bits in front and all is as expected.
There is one more thing. Say you got a negative value from a register, for example:
int[] registers = { 5172, -124, 0, 0 };
The calculation that just worked now gives us
1111111111111111111111111000010000000000000000000000000000000000
This time there are 64 bits printed, so it’s easy to see there are too many 1s in the beginning. They come from the int representation of -124. The solution is to mask them out:
int[] registers = { 5172, -124, 0, 0 };
long result = ((long) registers[0] & 0xFFFF) << 48
| ((long) registers[1] & 0xFFFF) << 32
| (registers[2] & 0xFFFF) << 16
| (registers[3] & 0xFFFF);
System.out.println(Long.toBinaryString(result));
0xFFFF is 16 1 bits, and & is the bitwise logical ‘and’, giving a 1 bit in the result only in positions where both operands have a 1 bit. Now -124 gets masked to 1111111110000100 so the result is the expected:
1010000110100111111111000010000000000000000000000000000000000
That should do it.

Java << operator (In this piece of code)

So I was reading the example source code from this Android page on ViewGroups,
and I came across these lines:
// Report our final dimensions.
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
resolveSizeAndState(maxHeight, heightMeasureSpec,
childState << MEASURED_HEIGHT_STATE_SHIFT));
So I hope to learn:
What does the << operator exactly do in Java?
What is happening in last line of the aforementioned snippet?
Thanks.
It isn't an operand, it is an operator. A bit-wise shift operator, to be exact.
Given x and y as operands, x << y shifts the bits of the x value y bits to the left. It is basically the same as multiplying by 2 to the power y.
<< is one of bit shifting operator.
It is quite offen we use higher 16 bits of one single 32 bits int for one thing and lower 16 bits of another thing.
childState << MEASURED_HEIGHT_STATE_SHIFT means childState is passing a height (in its lower 16 bits) which is expecting to be in higher 16 bits of the int passing to resolveSizeAndState().
What does the << operator exactly do in Java?
It's moving bits to the left. As mentioned in previous answers:
1111 1110 << 2
1111 1000 // Have added 0 from right
What is happening in last line of the aforementioned snippet?
Code is changing state. It's sometimes used to represent states. e.g.
state1 = 1 << 0;
state2 = 1 << 1;
state3 = 1 << 2;
so you have 3 unique states.
"<<" is a bit operator.
I quote the explaination from tutorial for Java
The signed left shift operator "<<" shifts a bit pattern to the left, and the signed right shift operator ">>" shifts a bit pattern to the right.
And also I quote an example from here
int a = 60; /* 60 = 0011 1100 */
int c = 0;
c = a << 2; /* 240 = 1111 0000 */
so you can see a << n is almost a*(2^n)
This is Bitwise and Bit Shift Operators. More info can be found at http://docs.oracle.com/javase/tutorial/java/nutsandbolts/opsummary.html
For Ex:
1111 1110 << 2
1111 1000 // Have added 0 from right
0001 1111 >> 3
0000 0011 // Will preserve MSB and shift it right
If you don't want the first bit to be preserved, you use (in Java, Scala, C++, C afaik, and maybe more) a triple-sign-operator:
1100 1100 >>> 1
0110 0110

Which bit actually shift the << operator?

I confused with an operator which provides arithmetic shifts <<, >> in Java
For example I have this binary number:
0000 0101 // It is actually 5 in dec system
And now I want to shift this number to the left by 2 positions. I am doing this ( this is only concept of shifting bits) :
0000 0101 << 2
And now I do not know: if I need to shift high bit by 2 positions and fill with zero in right side OR I need to shift whole number (101) by 2 positions?
Second option :)
For instance, 0110001 << 2 = 1000100
The other operators are:
signed right shift (>>).
0011001 >> 2 = 0000110
1011001 >> 2 = 1110110
The leftmost bit is used as left padding. This is done to propagate the sign bit (highest bit).
unsigned right shift (>>>)
1110001 >> 2 = 0011100
Since the number is considered unsigned, there is nothing to propagate, just pad with zeros!

Categories

Resources