Is there an Error with Unsigned Shift in Java ??? look at this: if you make an >>> Operation to a Byte: for (byte sourc = Byte.MIN_VALUE; sourc < Byte.MAX_VALUE; sourc++) { cat.info(sourc + " >>> 1 = "+ (byte)(sourc >> 1)); } this seems to not really work: look: -126>>>1 = -63 if you make this manually, you get this: -126 = (bin) 1000 0010 | | | +-------> the value 1000 0000 = -128 +--------------> this is the minus if you shift it RIGHT UNSIGNED, it should be: 1000 0010 >>> 1 = 0100 0001 = +65 this is clear: look: (original Java) should be!! 121 >>> 1 = 60 60 (OK) 122 >>> 1 = 61 61 (OK) 123 >>> 1 = 61 61 (OK) 124 >>> 1 = 62 62 (OK) 125 >>> 1 = 62 62 (OK) 126 >>> 1 = 63 63 (OK) 127 >>> 1 = 63 63 (OK) -128 >>> 1 =-64 64 -127 >>> 1 =-64 64 -126 >>> 1 =-63 65 -125 >>> 1 =-63 65 -124 >>> 1 =-62 66 -123 >>> 1 =-62 66 -122 >>> 1 =-61 67 -121 >>> 1 =-61 67 now, java does the following, due to the Java Language Spec: the >>> Operator makes a cast to int. then the result is processed, and we do a cast back to byte. with this in Mind, we can see the truth: (original Java) should be!! 121 >>> 1 = 60 60 (OK) 122 >>> 1 = 61 61 (OK) 123 >>> 1 = 61 61 (OK) 124 >>> 1 = 62 62 (OK) 125 >>> 1 = 62 62 (OK) 126 >>> 1 = 63 63 (OK) 127 >>> 1 = 63 63 (OK) -128 >>> 1 = 2147483584 64 -127 >>> 1 = 2147483584 64 -126 >>> 1 = 2147483585 65 -125 >>> 1 = 2147483585 65 -124 >>> 1 = 2147483586 66 -123 >>> 1 = 2147483586 66 -122 >>> 1 = 2147483587 67 -121 >>> 1 = 2147483587 67 now we see: the unsigned shift Operator DOES really shift a negative Value, without care about the Signs bit, so all Negative does get positive!!! the problem is the cast to byte!!! ---- this is a possible Solution: for (source = Byte.MIN_VALUE; source < Byte.MAX_VALUE; source++) { cat.info(source + " >>> 1 = "+ ( (byte)(source >> 1) & Byte._0111_1111 ) ); } ---- VisualC++ has similar shifting problems, requiring explicit casts to signedness and size to do it correctly. Perhaps the same is true of Java? ---- But this is '''not a problem''' since, according to Java specification, the byte is augmented to an int before shifting. ---- Yes, that's true, if you say: the Java language works correctly, because of the Specification. You are Right!! This is not a Bug! But, that's Useless if you need a '''really''' Unsigned Shift for a Byte!! ---- I thought everybody knew that '''A "FEATURE" IS A DOCUMENTED BUG'''. ---- ''Not a bug, but still a problem. The bit-fiddling code I write in Java is a mixture of occasional obscure type-promotion errors and an otherwise ridiculously defensive explicit-casting programming style. Much more so than in C, where you have unsigned types. I've recently found some very simple CommonLisp primitives for manipulating sub-bytes of integers ''extremely'' handy - it would be great to see them added to other languages. Details at http://www.lispworks.com/reference/HyperSpec/Body/12_aacb.htm -- LukeGorrie'' ----- Here's a Way to do it: /** * Method unsigned. * * does the following Mapping: * * (byte)0 = +0 = b0000_0000 ---> 0 (int) * (byte)1 = +1 = b0000_0001 ---> 1 (int) * . * . * (byte)127= +127 = b0111_1111 ---> 127(int) * (byte)128= -128 = b1000_0000 ---> 128(int) * (byte)129= -127 = b1000_0001 ---> 129(int) * . * . * (byte)253= - 3 = b1111_1101 ---> 253(int) * (byte)254= - 2 = b1111_1110 ---> 254(int) * (byte)255= - 1 = b1111_1111 ---> 255(int) * * The way how to do this is here: * * http://forum.java.sun.com/thread.jsp?forum=4&thread=296372 * Topic: Unsigned Byte Possible? * * * * How does this work ??? * * * look: * * +127(int) = b1111111 * -128(int) = b11111111111111111111111110000000 & 0xFF = b10000000 * -127(int) = b11111111111111111111111110000001 & 0xFF = b10000001 * * so, this is WORKING !!!!!!! * * @param b * @return int */ int unsigned(byte b) { return ((int)b)&0xFF; //so, only the lowest Byte of the int is taken. } ----- Now you can: byte b = (byte)128; x = unsigned(b) >>> 1 ---- See ArithmeticShiftingConsideredHarmful