Unsigned Bitwise Shift Operators

Aug 05 2007 Published by under Flash

A typo in Foundation ActionScript 3.0 Animation: Making Things Move! was just pointed out to me.

For years I used the bitwise shift operators to manipulate 24-bit colors. For example, if you have the hex color c=0xFF9900, you can get the red channel by saying:

c >> 16

This gives you 0xFF or 255. The green channel is found by shifting 8 places and masking with 0xFF:

c >> 8 & 0xFF

And the blue channel you can get with simple masking, since it’s already in the far right position:

c & 0xFF

So, jumping into 32-bit colors, where you also have an alpha channel as the two left-most bytes, i.e. 0xFFCC9966, where FF is the alpha, CC is red, 99 green, and 66 blue, it’s obvious that you just do the same thing, and shift 24 places for the alpha channel. However, since the bitwise operators were designed to work with signed Numbers, which can’t hold 32 bits of unsigned data, you can get some pretty strange results when you start using them with such large values. You can try extracting the four channels and tracing them out like so:

[as]var c:uint = 0xffcc9966;
var a:uint = c >> 24;
var r:uint = c >> 16 & 0xff;
var g:uint = c >> 8 & 0xff;
var b:uint = c & 0xff;


You might expect this to trace out:


Instead, you get:


This is because of the wraparound nature of signed numbers. You go over the max positive value, and it wraps around to the lowest negative value. You could go ahead and mask it out with 0xFF again, as the rightmost bytes are still the values you want:

var a:uint = c >> 24 & 0xff;

But the correct way of handling it would be to use the unsigned bitwise shift operators, like so:

[as]var a:uint = c >>> 24;
var r:uint = c >>> 16 & 0xff;
var g:uint = c >>> 8 & 0xff;
var b:uint = c & 0xff;[/as]

These operate in the same way as the regular bitwise shift operators, but are designed to work correctly with unsigned ints.

I’m putting this up here in case any of you run into this in the book, so I have a place to point you to when you email me. :)

2 responses so far. Comments will be closed after post is one year old.