I have changed it slightly to this:-Sudhir Srinivasan wrote: . . .
[list]bitwise NOT [~] . . . . . .
Yes, it is a certain number of bits, but you need to go through the Java Language Specification (J7 edition) to find out how many. In the case of … where i and j are both integer primitives, the number of bits shifted is always j & size - 1, where size is the number of bits in i after promotion, 32 for anything other than a long. That means that only the rightmost 5 (6 for a long) bits in j are used to determine the distance to shift. Although you have shown 8‑bit numbers, the shift operations would promote them to ints. If you haven't come across i & j - 1 before, it is a bit like i % j, but j must be an integer obtainable from 2ⁱ, and the result is always ≥ 0. Does that answer your question about negative shifts? They will be converted to 0 or a positive number less than the number of bits in the left operand.Sudhir Srinivasan wrote: . . . bitshift operators - shift or move the bit(s) a certain number of positions to the left or right. . . .
Forget that you have ever heard the term “sign bit” except with S&M (=Sign & magnitude) numbers. Java does not use S&M integers (but IEEE754 floating‑point numbers do actually have S&M format. Their MSB is 1=negative 0=positive). The MSB in complimentary integers determines the value. Say that the spare bits at the left are filled with the same value as the MSB, 1 or 0, not negative and positive.Sudhir Srinivasan wrote: . . .
Signed
>> operation: bit(s), in a binary value, shifted out on the right are discarded. The existing bit(s) move n positions to the right [as the shifted out bit(s)]
thereby facilitating the shifting in of bit(s) at the far left. Here, bit(s) shifted in depend on the signed magnitude or sign extension[>> operator preserves the sign]
of the binary value. 0 is shifted in if the sign bit [aka MSB] is positive and 1 if the sign bit is negative. . . .
That link's not javadoc, but the Java Tutorials. They are useful for masks, rapid remainders by powers of 2, particularly when you want to go from hash code to array index (never < 0, never ≥ array.length, so never throws out of bounds exceptions), cyphers, etc. As the link you posted shows, they are less useful to beginners.Sudhir Srinivasan wrote: . . .
E) My questions / doubts:
1. Java being a higher level language, are such processor level operations useful in java programming? If yes, in which situations are they useful i.e
when can they be used?....given that even the javadocs devotes only a single small web page to it.
2. Why do the signed left-shift operator & unsigned right-shift operators ignore the sign bit and always shift in 0's [unlike the signed right-shift operator]?
3. How does the signed shift operators [right and left-shift] differ from the unsigned right-shift operator?....i.e do they all operate at the bit level or does each
operator conduct the shifting process in a different manner behind the scenes.
Much appreciated if the responders / moderators give answers with sample code.
Thanks,
Sudhir
Campbell Ritchie wrote:Try it like this
~0b0000_0001 == 0b1111_1110
… and it becomes a lot clearer.
Campbell Ritchie wrote:You are right about & ^ |. Remember their precedences, and that they are overloaded to operate on booleans, too.
Campbell Ritchie wrote:
Yes, it is a certain number of bits, but you need to go through the Java Language Specification (J7 edition) to find out how many.
Campbell Ritchie wrote:
In the case of … where i and j are both integer primitives, the number of bits shifted is always j & size - 1, where size is the number of bits in i after promotion, 32 for anything other than a long. That means that only the rightmost 5 (6 for a long) bits in j are used to determine the distance to shift. Although you have shown 8‑bit numbers, the shift operations would promote them to ints. If you haven't come across i & j - 1 before, it is a bit like i % j, but j must be an integer obtainable from 2ⁱ, and the result is always ≥ 0. Does that answer your question about negative shifts? They will be converted to 0 or a positive number less than the number of bits in the left operand.
Campbell Ritchie wrote:
That link's not javadoc, but the Java Tutorials.
Campbell Ritchie wrote:
They are useful for masks, rapid remainders by powers of 2, particularly when you want to go from hash code to array index (never < 0, never ≥ array.length, so never throws out of bounds exceptions), cyphers, etc. As the link you posted shows, they are less useful to beginners.
Left shift moves the MSB off the number so it is going to vanish anyway, and unsigned right shift is programmed to shift in 0s. Probably done somewhere on the chip. Don't know any more. As far as I know they are all implemented similarly, probably at the level of the chip with NOT, AND, OR, XOR and shift circuits. Don't call left shift signed;......
Campbell Ritchie wrote:
.....it is only right shift that is signed or unsigned. Signed right shift maintains + as + and - as -. Unsigned right shift if both operands are not 0 gives a positive result. Left shift can give + or - depending on whether you get overflow and (if you keep shifting to the left long enough), will give you 0.
Campbell Ritchie wrote:
You will realise that if left shift is like repeated doubling, signed right shift is like repeated halving.
i >> 3 equals i ÷ 2³ with the usual conventions of integer arithmetic.
It means they are intended to get different results, same sign or converted to a positive number. Depends what use you intend to make of them. If you hash a long into an int, you may prefer to have the left half of the number filled with 0s, so use >>>Remember that >>> has a higher precedence than &^|.Sudhir Srinivasan wrote: . . .
Does this mean >> operator is more ideal for signed twos complement binary numbers while the >>> operator is more useful for only positive numbers. . . .
Sudhir Srinivasan wrote: . . .
Got it. left shift is equivalent to left-operand * 2^n while signed right-shift is left-operand / 2^n where 'n' is the shift distance.
As logical and and logical xor and logical or and and andSudhir Srinivasan wrote: . . . How do they operate on booleans? . . .
Campbell Ritchie wrote:
153 ÷ 8 = 19
153 × 8 = 1224
Only people get confused between ^ used to mean exponentiation and ^ meaning XOR. Look here for a bit more information about superscript numbers...
Campbell Ritchie wrote:...I have failed to find superscript n, however.
Campbell Ritchie wrote:
As logical and and logical xor and logical or and and andSudhir Srinivasan wrote: . . . How do they operate on booleans? . . .
Campbell Ritchie wrote:Java Language Specification (JLS) J7 again.
Those bits of the JLS have been surprisingly clear, haven't they!
Well done finding that. It was in the same sheet of Unicode as some of the other superscripts I found, and I still managed to miss it.Sudhir Srinivasan wrote: . . .
Campbell Ritchie wrote:...I have failed to find superscript n, however.
This, hopefully, sets right the anomaly above.