I would think it is 00010010
i.e. it tries to maintain the sign bit as is
On the other hand, the logical left shift by 1 pos would be
10010010
Is this correct?
For left shift, arithmetic and logical shift are the same.
The difference is for right shift only, where an arithmetic right shift will copy the old MSB to the new MSB after having shifted, thus keeping a negative number from being converted to a positive when shifting.
Wikipedia has a more detailed explanation.
In Java << is a logical left-shift. 0 is always added as the LSB.
(Do note that Java will promote the [byte] value in question, so care must be taken to mask back to an octect! Otherwise you'll keep the shifted bit(s), which might have included "1".)
However, the Wikipedia article on Arithmetic shift indiciates that an arithmetic left shift may result in an overflow error:
...Note that arithmetic left shift may cause an overflow; this is the only way it differs from logical left shift.
(This is not the case in Java, but just to keep in mind.)
Happy coding.
Yes it is correct.
The arithmetic left shift of x by n places is equal to x * (2^n). So in your example is the ar-left-shift of 01001001 by 1 place equal to 10010010 (73 * 2¹ = 146).
You are correct when you left shift by 1 bit postion. It equals 10010010.
when you shift 4 bits to the left as follows, you get the following answer.
01001001 << 4 = 10010000
when you shift 4 bits to the right as follows, you get the following answer.
01001001 >> 4 = 00000100
Bits that are left empty as a result of shifting are filled with zeros.
Related
private static long permute(byte[] table, int srcWidth, long src) {
long dst = 0;
for (int i=0; i<table.length; i++) {
int srcPos = srcWidth - table[i];
dst = (dst<<1) | (src>>srcPos & 0x01);
}
return dst;
}
here dst = (dst<<1) | (src>>srcPos & 0x01); how does this work?? i am assuming | is an OR operator?
One way to think about the bitwise "and" and "or" operations are as ways to set (turn on) and reset (turn off) bits in your result.
You think as one operand as your "mask" - ones and zeros that represent what needs to be set or reset. The other operand is going to be "masked" by that "mask". In the following way:
If the operator is &, then each bit in the "mask" that is zero is going to be zero in the result. Each bit that is 1 is going to have the value from the other operand.
So for example result = x & 0b11111111_11111111_11111111_11110111 (that big number is our mask and I'm showing it in binary) is going to have all the bits the same as x, except the fourth bit from the right, which is going to be 0, no matter if it's 0 or 1 in x.
So doing & with a "mask" is considered to be a "bit-reset" operation, or a "zeroing" operation.
For the | (or) operator, you can think of it as a "bit-set" operation. Every bit in the mask that is 1 is going to be 1 in the result. Every bit that is 0 is going to have whatever is in the other operand. So in the result, all the bits that were 1 in the mask are going to be set.
For example result = x | 0b1000 is going to have all the bits that were in x, except the fourth bit from the right, which is going to be 1 regardless of what it was in x.
Writing masks in binary is long and is a pretty recent thing in Java, so you are more likely to see masks written in hexadecimal. In this case 0xfffffff7 for the & example, and 0x8 for the | example.
Now let's look at your expression with a "mask" point of view:
dst<<1 means shifting dst by 1. All its bits are moved one position to the left, and the rightmost bit is set to zero. In essence, this is "making room" for something in the rightmost bit.
In the right parenthesis, the shift operator has precedence, so it is evaluated first. src is moved srcPos positions to the right. So the bit that was srcPos+1 places from the right is now the rightmost bit.
Now we "mask" that with 0x01. That is, 0b00000000_00000000_00000000_00000001. This is an & mask, so everything that is not the rightmost bit is going to be zero. Only the rightmost bit is saved. The end result is that it's the bit that used to be in the srcPos+1 place in src, and only that bit - all the rests are reset.
And now we "mask" this with the dst<<1 thing that we prepared. Since it is an | operation, it's a "setting" mask. Our mask only has one significant bit - the one that we didn't erase in the & operation. And it is on the rightmost position. If it's 1, it will be 1 in the result, and if it's 0, it will be 0 in the result (because the left operand has zero in that position).
So basically what it does is:
Push the bits in dst to the left.
Place the bit from the srcPos + 1 place from the right in the rightmost bit of it.
If the values in table are all unique positions between 0 and srcWidth, then this will give you a scrambling of the bits of src - in each round one bit will be pushed into dst based on the value of table[i].
" | " is Binary OR Operator which copies a bit if it exists in either operand.
as an example :
A|B
will give 61 which is 0011 1101.
" || " is called Logical OR Operator. If any of the two operands are non-zero, then the condition becomes true. as an example:
(A || B) is true.
| is bitwise OR not a logical OR
A bitwise OR operates on every bit in that long individually. This changes it's value, which is not the same as defining it.
Breaking down this line:
dst = (dst<<1) | (src>>srcPos & 0x01);
dst<<1 // means left shift 1 place. The same as multiply by 2. Zeros lowest bit.
src>>srcPos // means right shift srcPos places. The same as divide by 2 to the srcPos
// this puts the selected bit in the lowest place
& 0x01 // means set every bit to zero except the rightmost one which will stay the same
(src>>srcPos & 0x01) // means give me the value of the src bit at srcPos
(dst<<1) | (src>>srcPos & 0x01); // means shift dst left and put a src bit at the end
Here the bitwise OR works like it's appending a bit. That only works because the bits that won't be used have been carefully zero'ed on each side.
As the loop goes around table is controlling what bit to sample from src and whatever it picks is appended to the right end of dst. Thus table controls how src is permuted.
Operand1 ShiftOperator Operand2
Shift Rule
If either of the Operand is Negative don't forget to calculate its 2's complement since Negative integers is stored in Memory using 2's complement
Mask Operand2 with 0x1F
Right shift
81814621>>-12 = 78
81814621>>>-12 = 78
OK!!
Right shift (Operand1 is NEGATIVE)
-81814621>>-12 = -79
-81814621>>>-12 = 4017
Why different?
Left shift
21<<-12 = 22020096
-21<<-12 = -22020096
Unlike Right shift no matter Operand1 is Positive/Negative
only sign get changed instead value
Thanks for all of your support! now i have a better idea on it...:)
Wherever you got that from, it's wrong. Operand2 cannot possibly be either negative or have anything at all in its leftmost five bits after masking it with 0x1F. There is nothing in the Java Language Specification about taking the twos-complement of the shift distance, or using its left-most five bits. Read what it really says. Don't rely on arbitrary sources, or just make it up.
EDIT -81814621 is 0xFFFFFFFFFB1F9BA3, -12 is 0xFFFFFFFFFFFFFFF4, bottom five bits of that is 0x14 or 20, right shift the first operand by 20 gives 0xFFFFFFFFFFFFFFB1, which is -79.
The "rule" about what to do with the right-hand side operator of the shift is there because the list of values of the right operand that truly make sense is very short: for ints the range is from zero to 31, inclusive; for longs, it is zero to 63.
All other values of int on the right-hand side need to be converted to a value in the specified range. The "rule" spells out the process - i.e. re-interpreting the number as positive (that's what the two's complement is about), then masking off the higher bits, keeping the last five.
In contrast, the left operand can retain its full range. The only difference that you are experiencing has to do with the difference between >> and >>>, that is, between an operator that interprets the left-hand side operand as signed for shifting, and the one that interprets it as unsigned.
The purpose behind the >>> operator is explained in this answer. In your example, when you right-shift a negative number with the two operators, the >> leaves the number negative by sigh-extending it (i.e. shifting ones on the left) while >>> makes it positive by shifting in zeros.
I understand what the unsigned right shift operator ">>>" in Java does, but why do we need it, and why do we not need a corresponding unsigned left shift operator?
The >>> operator lets you treat int and long as 32- and 64-bit unsigned integral types, which are missing from the Java language.
This is useful when you shift something that does not represent a numeric value. For example, you could represent a black and white bit map image using 32-bit ints, where each int encodes 32 pixels on the screen. If you need to scroll the image to the right, you would prefer the bits on the left of an int to become zeros, so that you could easily put the bits from the adjacent ints:
int shiftBy = 3;
int[] imageRow = ...
int shiftCarry = 0;
// The last shiftBy bits are set to 1, the remaining ones are zero
int mask = (1 << shiftBy)-1;
for (int i = 0 ; i != imageRow.length ; i++) {
// Cut out the shiftBits bits on the right
int nextCarry = imageRow & mask;
// Do the shift, and move in the carry into the freed upper bits
imageRow[i] = (imageRow[i] >>> shiftBy) | (carry << (32-shiftBy));
// Prepare the carry for the next iteration of the loop
carry = nextCarry;
}
The code above does not pay attention to the content of the upper three bits, because >>> operator makes them
There is no corresponding << operator because left-shift operations on signed and unsigned data types are identical.
>>> is also the safe and efficient way of finding the rounded mean of two (large) integers:
int mid = (low + high) >>> 1;
If integers high and low are close to the the largest machine integer, the above will be correct but
int mid = (low + high) / 2;
can get a wrong result because of overflow.
Here's an example use, fixing a bug in a naive binary search.
Basically this has to do with sign (numberic shifts) or unsigned shifts (normally pixel related stuff).
Since the left shift, doesn't deal with the sign bit anyhow, it's the same thing (<<< and <<)...
Either way I have yet to meet anyone that needed to use the >>>, but I'm sure they are out there doing amazing things.
As you have just seen, the >> operator automatically fills the
high-order bit with its previous contents each time a shift occurs.
This preserves the sign of the value. However, sometimes this is
undesirable. For example, if you are shifting something that does not
represent a numeric value, you may not want sign extension to take
place. This situation is common when you are working with pixel-based
values and graphics. In these cases you will generally want to shift a
zero into the high-order bit no matter what its initial value was.
This is known as an unsigned shift. To accomplish this, you will use
java’s unsigned, shift-right operator,>>>, which always shifts zeros
into the high-order bit.
Further reading:
http://henkelmann.eu/2011/02/01/java_the_unsigned_right_shift_operator
http://www.java-samples.com/showtutorial.php?tutorialid=60
The signed right-shift operator is useful if one has an int that represents a number and one wishes to divide it by a power of two, rounding toward negative infinity. This can be nice when doing things like scaling coordinates for display; not only is it faster than division, but coordinates which differ by the scale factor before scaling will differ by one pixel afterward. If instead of using shifting one uses division, that won't work. When scaling by a factor of two, for example, -1 and +1 differ by two, and should thus differ by one afterward, but -1/2=0 and 1/2=0. If instead one uses signed right-shift, things work out nicely: -1>>1=-1 and 1>>1=0, properly yielding values one pixel apart.
The unsigned operator is useful either in cases where either the input is expected to have exactly one bit set and one will want the result to do so as well, or in cases where one will be using a loop to output all the bits in a word and wants it to terminate cleanly. For example:
void processBitsLsbFirst(int n, BitProcessor whatever)
{
while(n != 0)
{
whatever.processBit(n & 1);
n >>>= 1;
}
}
If the code were to use a signed right-shift operation and were passed a negative value, it would output 1's indefinitely. With the unsigned-right-shift operator, however, the most significant bit ends up being interpreted just like any other.
The unsigned right-shift operator may also be useful when a computation would, arithmetically, yield a positive number between 0 and 4,294,967,295 and one wishes to divide that number by a power of two. For example, when computing the sum of two int values which are known to be positive, one may use (n1+n2)>>>1 without having to promote the operands to long. Also, if one wishes to divide a positive int value by something like pi without using floating-point math, one may compute ((value*5468522205L) >>> 34) [(1L<<34)/pi is 5468522204.61, which rounded up yields 5468522205]. For dividends over 1686629712, the computation of value*5468522205L would yield a "negative" value, but since the arithmetically-correct value is known to be positive, using the unsigned right-shift would allow the correct positive number to be used.
A normal right shift >> of a negative number will keep it negative. I.e. the sign bit will be retained.
An unsigned right shift >>> will shift the sign bit too, replacing it with a zero bit.
There is no need to have the equivalent left shift because there is only one sign bit and it is the leftmost bit so it only interferes when shifting right.
Essentially, the difference is that one preserves the sign bit, the other shifts in zeros to replace the sign bit.
For positive numbers they act identically.
For an example of using both >> and >>> see BigInteger shiftRight.
In the Java domain most typical applications the way to avoid overflows is to use casting or Big Integer, such as int to long in the previous examples.
int hiint = 2147483647;
System.out.println("mean hiint+hiint/2 = " + ( (((long)hiint+(long)hiint)))/2);
System.out.println("mean hiint*2/2 = " + ( (((long)hiint*(long)2)))/2);
BigInteger bhiint = BigInteger.valueOf(2147483647);
System.out.println("mean bhiint+bhiint/2 = " + (bhiint.add(bhiint).divide(BigInteger.valueOf(2))));
I looked in this question to understand why there is no arithmetic left shift operator in most languages including Java . But then how do we deal with negative integers because left shifting would throw it away . Take for example -2^5 where the result should be negative .
No, the sign bit will never be thrown out by left shift unless you commit an overflow. Reason? In two's complement encoding the negative number has all ones on te left side, where a positive number would have all zeros. It's like the sign bit is replicated to the right. BTW this is exactly why the term "sign extension" makes sense, which is how the default right-shift works in Java.
int i = -1;
System.out.format("%3d = %s\n", i, Integer.toBinaryString(i));
i <<= 5;
System.out.format("%3d = %s\n", i, Integer.toBinaryString(i));
prints
-1 = 11111111111111111111111111111111
-32 = 11111111111111111111111111100000
My best answer for that, would have to be to just change the sign before and after the operation. It might appear too obvious but the thing is that the bits get changed in a particular way when the sign changes
I can't find out what << means in Java because I can't search for it on Google - I am absolutely lost!
The code in question is:
public int getRGB() {
return ((red << 16) | (green << 8) | blue);
}
It's taken from: http://java.sun.com/docs/books/tutorial/essential/concurrency/example/ImmutableRGB.java
I would really appreciate someone telling me, thanks!
Left shift of the bits
If red == 4 (which in binary is: 00000100) then red << 16 will insert sixteen 0-bits at its right, yielding: 000001000000000000000000 which is 262144 in decimal
Q. What is this?
A. An "operator"
Q. How do I get to know about operators in java?
A. Google for "Java operators"
And the result is this:
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 shift a number of bits. It is equivalent to multiplying by two that many times.
It's used for setting specific bits in a byte, or specific bytes in a word.
It is the left shift operator. Here's some more information on shift operators from the Java Tutorial.
In your example code the three integer values: red, green and blue will typically have values 0-255. Hence, it is possible to combine these values and represent them as a single integer by shifting the red value by 16 bits, shifting the green value by 8 bits and then performing a bitwise-OR operation to combine the values.
its a bit shift. search for operators java, it will return you detailed explanations.
"<<" means left shift the bits of a value.
">>" means right shift the bits of a value.
example:
int a = 5; //the binary value of 5 is 101
a = a << 3; //left shift 3 bits on 101, 101 000<< add 3 bits(0) on the right, become '101000'
System.out.println(a); //this will display 40, the decimal for '101000'
int b = 9; //the binary value of 8 is 1001
b = b >> 3; //right shift 3 bits on >>000 1001 add 3 bits(0) on the left, truncate the last 3 bits on the right become '001'
System.out.println(b); //this will display 1, the decimal for '001'
Its a left bit shift
Its left shifting and convert Red, Green, Blue into 24 bit Number