Converting binary to signed decimal in Actionscript

If you’re like me, you may have been living these past few years taking advantage of the luxury of new sleek programming languages that rarely require you to do low level operations. One of the old skills I seem to always let get rusty enough is bitwise operation. Most code written with the help of frameworks doesn’t require this type of code and most programmers probably don’t even bother to learn it anymore.

I came into an instance yesterday where I needed to do some bitwise work in actionscript. The code was reading a bytestream from a binary file and converting to an array of numbers. Since this project was ported from Java (by someone else), a simple operation was overlooked. It was taking the binary number and converting it to a signed short. Since actionscript doesn’t have the same casting mechanisms conversion isn’t as straight forward in java.

In java the operation looked like this:

//  binary: 1111 1111 1111 0001
int hexValue = 0xFFF1;
 
short value = (short)(hexValue);
// value = -15 

Since short in java is always stored with a signed bit, the cast appropriately set the value at -15.

The way this was translated into Actionscript looked liked this:

//  binary: 1111 1111 1111 0001
var hexValue:int = 0xFFF1;
 
var value:int = int(hexValue);
// value = 65521  // Wrong! 

Actionscript has no concept of casting for primitives so the int(hexValue) doesn’t do anything at all.

Here is the workaround I came up with, I suspect there is a shorter way to get the same result but I can’t think of one right now.

//  binary: 1111 1111 1111 0001
var hexValue:int = 0xFFF1;
 
// get everything except the signed bit "111 1111 1111 0001"
var unsignedValue:Number = (hexValue & 0x7FFF);  
// unsignedValue now equals 32,753
 
var signedValue:Number = unsignedValue;
 
// if the signed flag is set, flip the value
if ((hexValue >> 15) == 1) {
    signedValue = unsignedValue - 0x8000;   // 0x800 =  32,768 (maximum 15 bit number)
}
 
// signedValue = -15 

  • Christian

    this doesn’t work for example for a value like -132768
    -132768 should become -1696 not 31072
    shouldn’t the line:
    if ((hexValue >> 15) == 1)
    be:
    if (((hexValue >> 15) & 1) == 1)
    ???
    correct me if I’m wrong…

  • Tea

    um. this particular example deals with 16bit numbers so they have a maximum value of 65,535.

    You could do this with a 32 bit number:

    var hexValue:int = 0x800206A0

    var unsignedValue:Number = (hexValue & 0x7FFFFFFF);
    // unsignedValue now equals 132,768

    var signedValue:Number = unsignedValue;

    // if the signed flag is set, flip the value
    if ((hexValue >> 31) == 1) {
    signedValue = unsignedValue – 0x80000000;
    }