Thursday, 16 August 2007

Pass out BIG Number from Flash

Working with big number just inside flash is all sweet (Number.MAX_VALUE approx. 1.7976931348623158e+308) , but when you need to pass it out by xml it would be a pain because it would become a 14 decimal places scientific notation somewhere between 2^49 and 2^50. (which is the same behaviour as most of the languages).

2^49 = 562949953421312
2^50 = 1125899906842624 which to string would be 1.12589990684262e+15 (note that a "4" is missing at the end)

So passing out big number as string and convert it back to a number from it would not work (obviously)!

We were using bit mask for marking selections, i.e. 101001 indicates 0,3 and 5 are selected. I didn't notice this issue until we have 50 selections and people are choosing multiple (i.e. 50 and something else, which means 2^49 plus some more). I have been finding a easy solution but apparently there is none. Therefore I've decided to do the following in ActionScript:

static function GenerateBitMask(listOfPowers:Array):Array{

var bitmask:Number = 0;
var bitmaskHead:Number = 0x0;
var bitmaskTail:Number = 0x0;

// Loop through all selection
for (var index = 0; index<listOfPowers.length; index++) {
var indHead:Number = 0;
var indTail:Number = 0;

// if power > 32, set in bitmaskHea
if (listOfPowers[index] > 32){
indHead = listOfPowers[index] - 32;
bitmaskHead = bitmaskHead + (Math.pow(2, indHead -1));
}

// if power <= 32, set in bitmaskTai
else{
indTail = listOfPowers[index];
bitmaskTail = bitmaskTail + (Math.pow(2, indTail -1));
}
}

// Combine bitmaskHead and bitmaskTail to get bitmask for flash usag
bitmask = bitmaskHead * (Math.pow(2, 32)) + bitmaskTail;

var bitmaskArray:Array = new Array();
bitmaskArray[0]=bitmask;
bitmaskArray[1]=bitmaskHead;
bitmaskArray[2]=bitmaskTail;
return bitmaskArray;
}

I do have a reason for picking 32 as the magic number, but it doesn't really matter. The bitmaskTail and bitmaskHead are passed to the web application (which in this case .NET C#) and the web application need to reconstruct the number:

XmlNode bitmaskHead = selectionNode.Attributes["BitmaskHead"];
XmlNode bitmaskTail = selectionNode.Attributes["BitmaskTail"];
ulong bigNumber = Convert.ToUInt64(ulong.Parse(bitmaskHead.InnerText) * Math.Pow(2, 32) + ulong.Parse(bitmaskTail.InnerText));

To pass big number to flash is basically the reverse process. Anyway I hope there is an easier way so if anyone have something in mind please tell me. Otherwise let's live with this pain. :D

No comments:

Post a Comment