Search code examples
javaactionscript-3flashbit-manipulation

Why is AS3 right bit shift different than the same thing in Java?


Hard to explain without some code.. so

var junk:uint = uint(4294280300);

trace(junk.toString(2)); // returns 11111111111101011000010001101100
junk = junk >> 8;
trace(junk.toString(2)); // returns 11111111111111111111010110000100

and here is the Java part

long junk = 4294280300L;

System.out.println(Long.toBinaryString(junk)); // returns 11111111111101011000010001101100
junk = junk >> 8;
System.out.println(Long.toBinaryString(junk)); // returns 111111111111010110000100

What am I doing wrong? How can I achieve the same result in Java? I have tried using >>> instead of >> but it doesn't seem to work.


Solution

  • I don't know ActionScript at all, but it's for sure due to differences in the internal representation of numbers.

    The type uint of ActionScript seem indeed to be an unsigned integer coded on 32 bits. Additionally, the number appear to be converted into a signed integer before the right shift operation is performed. This counter-intuitive behavior explains the result.

    You don't have this problem in Java because long is an integer number coded on 64 bits, and the value 4294280300 perfectly fits into 64 bits. You would have observed the same result as in ActionScript if you have had used an int instead of a long.

    Let's look at what JavaScript does to better understand what appears to happen in ActionScript: JavaScript stores all numbers as double floating-point and you are sure to not lose precision on integers that can fit in 53 bits. Trying with the same value, see that you get the same result as in ActionScript if you use >>, but the same as Java if you use >>>.

    ON JavaScript side, it appears that >> a.k.a arithmetic shift converts first the value to 32-bit signed integer, while it doesn's with >>> a.k.a logical shift. That's weird, and wouldn't really surprising that ActionScript does something similar.

    Interestingly, python has no >>>operator, always does an arithmetic shift, and seems to work even beyond 64 bits.

    Given the popularity of this question or this one, >> vs. >>> is a common source of confusion in languages where the two operators exist.