Bit shift in Java - java

May be I am too tired.
Why dont't the following display the same value?
int x = 42405;
System.out.println(x << 8);
System.out.println((x &0x00ff) << 8);
The lower bits should be clear in both cases

EDIT: Okay, I'm leaving the bottom part for posterity...
If x is int, then it's pretty simple: x << 8 will have the same value as x & 0xff if and only if none of the "middle" 16 bits are set:
The top 8 bits of x will be rendered irrelevant by the left shift
The bottom 8 bits of x are preserved by the masking
If there are any of the "middle" 16 bits set, then x & 0xff will differ from x in a bit which is still preserved by the shift, therefore the results will be different.
I don't understand why you'd expect them to always give the same results...
I'm going to assume that the type of x is byte, and that it's actually negative.
There's no shift operation defined for byte, so first there's a transformation to int... and that's what can change depending on whether or not you've got the mask.
So let's take the case where x is -1. Then (int) x is also -1 - i.e. the bit pattern is all 1s. Shift that left by 8 bits and you end up with a bit pattern of 24 1s followed by 8 0s:
11111111111111111111111100000000 = -256
Now consider the second line of code - that's taking x & 0xff, which will only take the bottom 8 bits of the promoted value of x - i.e. 255. You shift that left by 8 bits and you end up with 16 0s, 8 1s, then 8 0s:
00000000000000001111111100000000 = 65280

Below, x is > 0xff , and in one case you mask away the upper 3 bytes, meaning you
you do (0x123 & 0x00ff) << 8 , which will be 0x23 << 8 And that is quite different from 0x123 << 8
int x = 0x123;
System.out.println(x << 8); //prints 74496
System.out.println((x &0x00ff) << 8); //prints 8960
And if x is a byte, it will get "promoted" to int before the shift, and if it's negative, it'll sign extend, and you get a whole lot of 1 bits set in the integer, which is masked away with &0xff in one case, and not masked away in the other
i.e.
byte x = (byte)0xAA; //x is negative
System.out.println(x << 8); //prints -22016
System.out.println((x &0x00ff) << 8); //prints 43520

Related

how does this unique if statement work in Java? [duplicate]

This question already has answers here:
What are bitwise shift (bit-shift) operators and how do they work?
(10 answers)
Closed 4 years ago.
I am trying to understand the shift operators and couldn't get much.
When I tried to execute the below code
System.out.println(Integer.toBinaryString(2 << 11));
System.out.println(Integer.toBinaryString(2 << 22));
System.out.println(Integer.toBinaryString(2 << 33));
System.out.println(Integer.toBinaryString(2 << 44));
System.out.println(Integer.toBinaryString(2 << 55));
I get the below
1000000000000
100000000000000000000000
100
10000000000000
1000000000000000000000000
Could somebody please explain?
System.out.println(Integer.toBinaryString(2 << 11));
Shifts binary 2(10) by 11 times to the left. Hence: 1000000000000
System.out.println(Integer.toBinaryString(2 << 22));
Shifts binary 2(10) by 22 times to the left. Hence : 100000000000000000000000
System.out.println(Integer.toBinaryString(2 << 33));
Now, int is of 4 bytes,hence 32 bits. So when you do shift by 33, it's equivalent to shift by 1. Hence : 100
2 from decimal numbering system in binary is as follows
10
now if you do
2 << 11
it would be , 11 zeros would be padded on the right side
1000000000000
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. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension [..]
left shifting results in multiplication by 2 (*2) in terms or arithmetic
For example
2 in binary 10, if you do <<1 that would be 100 which is 4
4 in binary 100, if you do <<1 that would be 1000 which is 8
Also See
absolute-beginners-guide-to-bit-shifting
Right and Left shift work on same way here is How Right Shift works;
The Right Shift:
The right shift operator, >>, shifts all of the bits in a value to the right a specified number of times. Its general form:
value >> num
Here, num specifies the number of positions to right-shift the value in value. That is, the >> moves all of the bits in the specified value to the right the number of bit positions specified by num.
The following code fragment shifts the value 32 to the right by two positions, resulting in a being set to 8:
int a = 32;
a = a >> 2; // a now contains 8
When a value has bits that are “shifted off,” those bits are lost. For example, the next code fragment shifts the value 35 to the right two positions, which causes the two low-order bits to be lost, resulting again in a being set to 8.
int a = 35;
a = a >> 2; // a still contains 8
Looking at the same operation in binary shows more clearly how this happens:
00100011 35 >> 2
00001000 8
Each time you shift a value to the right, it divides that value by two—and discards any remainder. You can take advantage of this for high-performance integer division by 2. Of course, you must be sure that you are not shifting any bits off the right end.
When you are shifting right, the top (leftmost) bits exposed by the right shift are filled in with the previous contents of the top bit. This is called sign extension and serves to preserve the sign of negative numbers when you shift them right. For example, –8 >> 1 is –4, which, in binary, is
11111000 –8 >>1
11111100 –4
It is interesting to note that if you shift –1 right, the result always remains –1, since sign extension keeps bringing in more ones in the high-order bits.
Sometimes it is not desirable to sign-extend values when you are shifting them to the right. For example, the following program converts a byte value to its hexadecimal string representation. Notice that the shifted value is masked by ANDing it with 0x0f to discard any sign-extended bits so that the value can be used as an index into the array of hexadecimal characters.
// Masking sign extension.
class HexByte {
static public void main(String args[]) {
char hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
byte b = (byte) 0xf1;
System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
}
}
Here is the output of this program:
b = 0xf1
I believe this might Help:
System.out.println(Integer.toBinaryString(2 << 0));
System.out.println(Integer.toBinaryString(2 << 1));
System.out.println(Integer.toBinaryString(2 << 2));
System.out.println(Integer.toBinaryString(2 << 3));
System.out.println(Integer.toBinaryString(2 << 4));
System.out.println(Integer.toBinaryString(2 << 5));
Result
10
100
1000
10000
100000
1000000
Edited:
Must Read This (how-do-the-bitwise-shift-operators-work)
I think it would be the following, for example:
Signed left shift
[ 2 << 1 ] is => [10 (binary of 2) add 1 zero at the end of the binary string] Hence 10 will be 100 which becomes 4.
Signed left shift uses multiplication...
So this could also be calculated as 2 * (2^1) = 4.
Another example [2 << 11] = 2 *(2^11) = 4096
Signed right shift
[ 4 >> 1 ] is => [100 (binary of 4) remove 1 zero at the end of the binary string] Hence 100 will be 10 which becomes 2.
Signed right shift uses division...
So this could also be calculated as 4 / (2^1) = 2
Another example [4096 >> 11] = 4096 / (2^11) = 2
It will shift the bits by padding that many 0's.
For ex,
binary 10 which is digit 2 left shift by 2 is 1000 which is digit 8
binary 10 which is digit 2 left shift by 3 is 10000 which is digit 16
Signed left shift
Logically
Simple if 1<<11 it will tends to 2048 and 2<<11 will give 4096
In java programming
int a = 2 << 11;
// it will result in 4096
2<<11 = 2*(2^11) = 4096
The shift can be implement with data types (char, int and long int). The float and double data connot be shifted.
value= value >> steps // Right shift, signed data.
value= value << steps // Left shift, signed data.
The typical usage of shifting a variable and assigning back to the variable can be
rewritten with shorthand operators <<=, >>=, or >>>=, also known in the spec as Compound Assignment Operators.
For example,
i >>= 2
produces the same result as
i = i >> 2

The method add mod 2^512

It's add modulo 2^512. Could you explain me why we doing here >>8 and then &oxFF?
I know i'm bad in math.
int AddModulo512(int []a, int []b)
{
int i = 0, t = 0;
int [] result = new int [a.length];
for(i = 63; i >= 0; i--)
{
t = (a[i]) + (int) (b[i]) + (t >> 8);
result[i] = (t & 0xFF); //?
}
return result;
}
The mathematical effect of a bitwise shift right (>>) on an integer is to divide by two (truncating any remainder). By shifting right 8 times, you divide by 2^8, or 256.
The bitwise & with 0xFF means that the result will be limited to the first byte, or a range of 0-255.
Not sure why it references modulo 512 when it actually divides by 256.
It looks like you have 64 ints in each array, but your math is modulo 2^512. 512 divided by 64 is 8, so you are only using the least significant 8 bits in each int.
Here, t is used to store an intermediate result that may be more than 8 bits long.
In the first loop, t is 0, so it doesn't figure in the addition in the first statement. There's nothing to carry yet. But the addition may result in a value that needs more than 8 bits to store. So, the second line masks out the least significant 8 bits to store in the current result array. The result is left intact to the next loop.
What does the previous value of t do in the next iteration? It functions as a carry in the addition. Bit-shifting it to the right 8 positions makes any bits beyond 8 in the previous loop's result into a carry into the current position.
Example, with just 2-element arrays, to illustrate the carrying:
[1, 255] + [1, 255]
First loop:
t = 255 + 255 + (0) = 510; // 1 11111110
result[i] = 510 & 0xFF = 254; // 11111110
The & 0xFF here takes only the least significant 8 bits. In the analogy with normal math, 9 + 9 = 18, but in an addition problem with many digits, we say "8 carry the 1". The bitmask here performs the same function as extracting the "8" out of 18.
Second loop:
// 1 11111110 >> 8 yields 0 00000001
t = 1 + 1 + (510 >> 8) = 1 + 1 + 1 = 3; // The 1 from above is carried here.
result[i] = 3 & 0xFF = 3;
The >> 8 extracts the possible carry amount. In the analogy with normal math, 9 + 9 = 18, but in an addition problem with many digits, we say "8 carry the 1". The bit shift here performs the same function as extracting the "1" out of 18.
The result is [3, 254].
Notice how any carry leftover from the last iteration (i == 0) is ignored. This implements the modulo 2^512. Any carryover from the last iteration represents 2^512 and is ignored.
>> is a bitwise shift.
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. The bit pattern is given by the left-hand operand, and the
number of positions to shift by the right-hand operand. The unsigned
right shift operator ">>>" shifts a zero into the leftmost position,
while the leftmost position after ">>" depends on sign extension.
& is a bitwise and
The bitwise & operator performs a bitwise AND operation.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
http://www.tutorialspoint.com/java/java_bitwise_operators_examples.htm
>> is the bitshift operator
0xFF is the hexadecimal literal for 255.
I think your question misses a very important part, the data format, i.e. how data are stored in a[] and b[]. To solve this question, I make some assumptions:
Since it's modulo arithmetic, a, b <= 2^512. Thus, a and b have 512 bits.
Since a and b have 64 elements, only 8 right-most bits of each elements are used. In other words, a[i], b[i] <= 256.
Then, what remains is very straightforward. Just consider each a[i] and b[i] as a digit (each digit is 8-bit) in a base 2^512 addition and then perform addition by adding digit-by-digit from right-to-left.
t is the carry variable which stores the value (with carry) of the addition at the last digit. t>>8 throws a way the right-most 8 bits that has been used for the last addition which is used as carry for the current addition. (t & 0xFF) gets the right-most 8 bits of t which is used for the current digit.
Since it's modulo addition, the final carry is thrown away.

Convert 32 bit fixed point value

In my Java application I need to interpret a 32 Bit Fixed Point value. The number format is as follows: The first 15 bits describe the places before the comma/point, the 16th bit represents the sign of the value and the following 16 bits describe the decimal places (1/2,1/4,1/8,1/16,...).
The input is a byte array with four values. The order of the bits in the byte array is little endian.
How can I convert such a number into Java float ?
Just do exactly what it says. Assume x is the 32bit fixed point number as int.
So, put the bits after the point, after the point, and don't use the sign here:
float f = (float)(x & 0x7fff_ffff) / (float)(1 << 16);
Put back the sign:
return x < 0 ? -f : f;
You will lose some precision. A float does not have 31 bits of precision, but your input does. It's easily adapted to doubles though.
Since the sign bit is apparently really in the middle, first get it out:
int sign = x & (1 << 16);
Join the two runs of non-sign bits:
x = (x & 0xFFFF) | ((x >> 1) & 0x7fff0000);
Then do more or less the old thing:
float f = (float)x / (float)(1 << 16);
return sign == 0 ? f : -f;
In case your input is little endian format, use the following approach to generate x:
int x = ByteBuffer.wrap(weirdFixedPoint).order(ByteOrder.LITTLE_ENDIAN).getInt();
where weirdFixedPoint is the byte array containing the 32 bit binary representation.

Get n Least Significant Bits from an Int

This seems fairly straightforward, but I cant find an answer. If I have an int X, what is the best way to get N least significant bits from this int, in Java?
This should work for all non-negative N < 33 32:
x & ((1 << N) - 1)
It's worth elaborating on how this works for N == 31 and N == 32. For N == 31, we get 1 << N == Integer.MIN_VALUE. When you subtract 1 from that, Java silently wraps around to Integer.MAX_VALUE, which is exactly what you need. For N == 32, the 1 bit is shifted completely out, so 1 << N == 0; then (1 << N) - 1 == -1, which is all 32 bits set.
For N == 32, this unfortunately doesn't work because (thanks, #zstring!) the << operator only shifts by the right side mod 32. Instead, if you want to avoid testing for that case specially, you could use:
x & ((int)(1L << N) - 1)
By shifting a long, you get the full 32-bit shift, which, after casting back to an int, gets you 0. Subtracting 1 gives you -1 and x & -1 is just x for any int value x (and x is the value of the lower 32 bits of x).
Ted's approach is likely to be faster but here is another approach
x << -N >>> -N
This shift all the bit up and then down to chop off the top bits.
int i = -1;
System.out.println(Integer.toBinaryString(i));
i = i << -5 >>> -5;
System.out.println(Integer.toBinaryString(i));
prints
11111111111111111111111111111111
11111
You can also use a mask. If you use the & bitwise operator you can then remove whatever bit you would want to remove (say the highest x bits);
int mask = 0x7FFFFFFF //Example mask where you will remove the
// most significant bit
// (0x7 = 0111b and 0xF = 1111b).
int result = numberToProcess & mask; //And apply the mask with the &bitwise op.
The disadvantage to this is that you will need to make a mask for each bit, so perhaps this is better seen as another method of approach in general.

How do shift operators work in Java? [duplicate]

This question already has answers here:
What are bitwise shift (bit-shift) operators and how do they work?
(10 answers)
Closed 4 years ago.
I am trying to understand the shift operators and couldn't get much.
When I tried to execute the below code
System.out.println(Integer.toBinaryString(2 << 11));
System.out.println(Integer.toBinaryString(2 << 22));
System.out.println(Integer.toBinaryString(2 << 33));
System.out.println(Integer.toBinaryString(2 << 44));
System.out.println(Integer.toBinaryString(2 << 55));
I get the below
1000000000000
100000000000000000000000
100
10000000000000
1000000000000000000000000
Could somebody please explain?
System.out.println(Integer.toBinaryString(2 << 11));
Shifts binary 2(10) by 11 times to the left. Hence: 1000000000000
System.out.println(Integer.toBinaryString(2 << 22));
Shifts binary 2(10) by 22 times to the left. Hence : 100000000000000000000000
System.out.println(Integer.toBinaryString(2 << 33));
Now, int is of 4 bytes,hence 32 bits. So when you do shift by 33, it's equivalent to shift by 1. Hence : 100
2 from decimal numbering system in binary is as follows
10
now if you do
2 << 11
it would be , 11 zeros would be padded on the right side
1000000000000
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. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension [..]
left shifting results in multiplication by 2 (*2) in terms or arithmetic
For example
2 in binary 10, if you do <<1 that would be 100 which is 4
4 in binary 100, if you do <<1 that would be 1000 which is 8
Also See
absolute-beginners-guide-to-bit-shifting
Right and Left shift work on same way here is How Right Shift works;
The Right Shift:
The right shift operator, >>, shifts all of the bits in a value to the right a specified number of times. Its general form:
value >> num
Here, num specifies the number of positions to right-shift the value in value. That is, the >> moves all of the bits in the specified value to the right the number of bit positions specified by num.
The following code fragment shifts the value 32 to the right by two positions, resulting in a being set to 8:
int a = 32;
a = a >> 2; // a now contains 8
When a value has bits that are “shifted off,” those bits are lost. For example, the next code fragment shifts the value 35 to the right two positions, which causes the two low-order bits to be lost, resulting again in a being set to 8.
int a = 35;
a = a >> 2; // a still contains 8
Looking at the same operation in binary shows more clearly how this happens:
00100011 35 >> 2
00001000 8
Each time you shift a value to the right, it divides that value by two—and discards any remainder. You can take advantage of this for high-performance integer division by 2. Of course, you must be sure that you are not shifting any bits off the right end.
When you are shifting right, the top (leftmost) bits exposed by the right shift are filled in with the previous contents of the top bit. This is called sign extension and serves to preserve the sign of negative numbers when you shift them right. For example, –8 >> 1 is –4, which, in binary, is
11111000 –8 >>1
11111100 –4
It is interesting to note that if you shift –1 right, the result always remains –1, since sign extension keeps bringing in more ones in the high-order bits.
Sometimes it is not desirable to sign-extend values when you are shifting them to the right. For example, the following program converts a byte value to its hexadecimal string representation. Notice that the shifted value is masked by ANDing it with 0x0f to discard any sign-extended bits so that the value can be used as an index into the array of hexadecimal characters.
// Masking sign extension.
class HexByte {
static public void main(String args[]) {
char hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
byte b = (byte) 0xf1;
System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
}
}
Here is the output of this program:
b = 0xf1
I believe this might Help:
System.out.println(Integer.toBinaryString(2 << 0));
System.out.println(Integer.toBinaryString(2 << 1));
System.out.println(Integer.toBinaryString(2 << 2));
System.out.println(Integer.toBinaryString(2 << 3));
System.out.println(Integer.toBinaryString(2 << 4));
System.out.println(Integer.toBinaryString(2 << 5));
Result
10
100
1000
10000
100000
1000000
Edited:
Must Read This (how-do-the-bitwise-shift-operators-work)
I think it would be the following, for example:
Signed left shift
[ 2 << 1 ] is => [10 (binary of 2) add 1 zero at the end of the binary string] Hence 10 will be 100 which becomes 4.
Signed left shift uses multiplication...
So this could also be calculated as 2 * (2^1) = 4.
Another example [2 << 11] = 2 *(2^11) = 4096
Signed right shift
[ 4 >> 1 ] is => [100 (binary of 4) remove 1 zero at the end of the binary string] Hence 100 will be 10 which becomes 2.
Signed right shift uses division...
So this could also be calculated as 4 / (2^1) = 2
Another example [4096 >> 11] = 4096 / (2^11) = 2
It will shift the bits by padding that many 0's.
For ex,
binary 10 which is digit 2 left shift by 2 is 1000 which is digit 8
binary 10 which is digit 2 left shift by 3 is 10000 which is digit 16
Signed left shift
Logically
Simple if 1<<11 it will tends to 2048 and 2<<11 will give 4096
In java programming
int a = 2 << 11;
// it will result in 4096
2<<11 = 2*(2^11) = 4096
The shift can be implement with data types (char, int and long int). The float and double data connot be shifted.
value= value >> steps // Right shift, signed data.
value= value << steps // Left shift, signed data.
The typical usage of shifting a variable and assigning back to the variable can be
rewritten with shorthand operators <<=, >>=, or >>>=, also known in the spec as Compound Assignment Operators.
For example,
i >>= 2
produces the same result as
i = i >> 2

Categories