# Right Shift >> 33 on an int

Rod Nichols

Greenhorn

Posts: 23

posted 14 years ago

- 0

I got this from the rules round up. The question goes like this

int c = 270;

c>>33;

What is the result ? The answer is 270>>1 but I am not sure how that is done.

270 in binary is :

0000 0000 0000 0000 0000 0001 0000 1110

When you right shift >>, the sign bit, which is the high order bit, is used to fill in the bits on the left as the bits on the right drop off. It would seem that if you >>33 on an int, then you would be left with all zeroes as all the bits would drop off the right side and the left would be filled in with the sign bit which is zero.

Is there a rule or something that I am not taking into account ?

Any clarification would be helpful.

As always thanks for all the great answers.

Rod

int c = 270;

c>>33;

What is the result ? The answer is 270>>1 but I am not sure how that is done.

270 in binary is :

0000 0000 0000 0000 0000 0001 0000 1110

When you right shift >>, the sign bit, which is the high order bit, is used to fill in the bits on the left as the bits on the right drop off. It would seem that if you >>33 on an int, then you would be left with all zeroes as all the bits would drop off the right side and the left would be filled in with the sign bit which is zero.

Is there a rule or something that I am not taking into account ?

Any clarification would be helpful.

As always thanks for all the great answers.

Rod

posted 14 years ago

- 0

Modulo reduction is applied to the right hand operand based on the width of the left hand operand.

given: l (shift operation) r

If l is an int (32 bits) r is reduced to (r % 32). In your example, (33 % 32) == 1. Or you can think of it as using only the first 5 low order bits of r.

If l is a long (64 bits) r would be reduced to (r % 64), in effect using only the first 6 low order bits of r.

See these threads for more:

http://www.javaranch.com/ubb/Forum24/HTML/010470.html

http://www.javaranch.com/ubb/Forum24/HTML/010607.html

[This message has been edited by JUNILU LACAR (edited July 10, 2001).]

given: l (shift operation) r

If l is an int (32 bits) r is reduced to (r % 32). In your example, (33 % 32) == 1. Or you can think of it as using only the first 5 low order bits of r.

If l is a long (64 bits) r would be reduced to (r % 64), in effect using only the first 6 low order bits of r.

See these threads for more:

http://www.javaranch.com/ubb/Forum24/HTML/010470.html

http://www.javaranch.com/ubb/Forum24/HTML/010607.html

[This message has been edited by JUNILU LACAR (edited July 10, 2001).]

Junilu - [How to Ask Questions] [How to Answer Questions]

Joshua Bloch

Author and "Sun God"

Ranch Hand

Ranch Hand

Posts: 124

posted 14 years ago

- 0

Hi. 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. You said:

> 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, in your case, 270 << 1 = floor(270/2) = 135. Easy!

------------------

Joshua Bloch

Author of Effective Java

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. You said:

> 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, in your case, 270 << 1 = floor(270/2) = 135. Easy!

------------------

Joshua Bloch

Author of Effective Java

Joshua Bloch <br />Author of <a href="http://www.amazon.com/exec/obidos/ASIN/0201310058/ref=ase_electricporkchop" target="_blank" rel="nofollow">Effective Java</a> and coauthor of <a href="http://www.amazon.com/exec/obidos/ASIN/032133678X/ref=ase_electricporkchop" target="_blank" rel="nofollow">Java Puzzlers</a>

Joshua Bloch

Author and "Sun God"

Ranch Hand

Ranch Hand

Posts: 124

posted 14 years ago
Joshua Bloch <br />Author of <a href="http://www.amazon.com/exec/obidos/ASIN/0201310058/ref=ase_electricporkchop" target="_blank" rel="nofollow">Effective Java</a> and coauthor of <a href="http://www.amazon.com/exec/obidos/ASIN/032133678X/ref=ase_electricporkchop" target="_blank" rel="nofollow">Java Puzzlers</a>

- 0

One note concerning JUNILU LACAR's reply: the % operator is not really a mod operator, it's a remainder operator. The difference is subtle but important. When the first operand is negative, the remainder operator returns a negative result, while a true mod operator always returns a positive result between 0 and (second operand - 1).

In the case of the shift operator's behavior, your really need a true mod operator. For example, (i >> -1) is (i >> 31), because -1 mod 32 is 31. That's why the Java Language Spec describes the shift operator in terms of masking rather than the % operator (Section 15.19).

For what it's worth, java.math.BigInteger provides both a mod method and a remainder method.

------------------

Joshua Bloch

Author of Effective Java

In the case of the shift operator's behavior, your really need a true mod operator. For example, (i >> -1) is (i >> 31), because -1 mod 32 is 31. That's why the Java Language Spec describes the shift operator in terms of masking rather than the % operator (Section 15.19).

For what it's worth, java.math.BigInteger provides both a mod method and a remainder method.

------------------

Joshua Bloch

Author of Effective Java

With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime. |