AS3 Numbers - get real

Skilled developers are hard to come by these days, that includes Flash/AS3/Flex developers. As the product I'm working on is very much dependent on a Flash based frontend, I've been forced to learn & work with AS3 & Flex recently.

It's a great experience, learning a new language - especially now that Silverlight is marching forward. As the old saying goes, know your enemy. Anyways, enough with the chit chatting, on with the problems.

Today I tried making a very simple functionality, I wanted to be able to select a number of images by making them highlight when selected, and dim out when deselected:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute">
	
	<mx:Script>
		<![CDATA[
			private function onClick():void
			{
				if(btnTest.alpha == 0.5)
					btnTest.alpha = 1;
				else
					btnTest.alpha = 0.5;
			}
		]]>
	</mx:Script>
	
	<mx:Button id="btnTest" click="onClick()" label="Click me!"/>
	
</mx:Application>



In this case the button is "selected" from the start (alpha = 1). When clicked, the alpha changes to half opaque (0.5), switches back to 1 when reclicked, and so forth. All working good.

But it's a bit hard to differentiate between selected and non selected, so let's change the alpha setting to 0.4 instead of 0.5:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute">
	
	<mx:Script>
		<![CDATA[
			private function onClick():void
			{
				if(btnTest.alpha == 0.4)
					btnTest.alpha = 1;
				else
					btnTest.alpha = 0.4;
			}
		]]>
	</mx:Script>
	
	<mx:Button id="btnTest" click="onClick()" label="Click me!"/>
	
</mx:Application>



But what's this, now we're only able to dim it, not reselect it. Why's that? Nothing's changed other than the alpha value. The problem becomes apparent if we trace out the buttons alpha value like so:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute">
	
	<mx:Script>
		<![CDATA[
			private function onClick():void
			{
				if(btnTest.alpha == 0.4)
					btnTest.alpha = 1;
				else
					btnTest.alpha = 0.4;
					
				mx.controls.Alert.show(btnTest.alpha.toString());
			}
		]]>
	</mx:Script>
	
	<mx:Button id="btnTest" click="onClick()" label="Click me!"/>
	
</mx:Application>



In case you don't have Flash 9 installed, or are just too lazy to click the button, the resulting Alert box shows the following value: 0.3984375 - obviously not quite the 0.4 we specified.

Ok, let's dumb it down a bit and do some quick testing:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute"
	initialize="onInitialize()">
	
	<mx:Script>
		<![CDATA[
			
			private function onInitialize():void
			{
				// true
				trace(0.4 == 0.4);
				
				// true
				var zeroPointFour:Number = 0.4;
				trace(zeroPointFour == 0.4);
				
				// true
				var secondZeroPointFour:Number = 0.4;
				trace(zeroPointFour == secondZeroPointFour);
				
				// false
				var testSprite:Sprite = new Sprite();
				testSprite.alpha = 0.4;
				trace(testSprite.alpha == 0.4);
				
				// 0.3984375
				trace(testSprite.alpha);
				
				// false - duh
				trace(0.3984375 == 0.4)
			}
			
		]]>
	</mx:Script>
	
</mx:Application>

Now this is where things start getting weird. We can obviously store the value 0.4 in a number (which is a 64 bit double-precision format according to the IEEE-754 spec). Furthermore, we're also able to compare two instances of Number with the value 0.4 and get the expected equality comparison result, true. Now, it would seem that as soon we set the alpha value on our Sprite, it's corrupted. Sprite inherits the alpha property from DisplayObject - which obviously lists alpha as a value of type Number.

Why does this happen? It's no problem storing the value 0.4 in a 64 bit double precision number:
Sign: +1
Exponent: -2
Mantisse: 1.6
Result: sign x 2exponent x mantisse => +1 x 2-2 x 1.6 = 0.4

It might be (and probably is) me not understanding something right. Can somebody explain to me how the Flash VM handles Numbers, and thereby, explain why this is happening? Is it perhaps not due to the VM's handling of Numbers, but instead just a simple matter of an odd implementation of the alpha property on DisplayObject?

kick it on DotNetKicks.com


Comments

Chris Velevitch | Jun 15th, 2008, 3:38 PM

The results you're seeing indicates the alpha value is stored as 8 bits:

0.4 = 0.01100110011001100110011001100110011001100110011001101 (64 bit precision)

0.01100110 = 0.3984375

Mark S. Rasmussen | Jun 15th, 2008, 4:04 PM

Chris,

Thanks for your comment. Do you know why the alpha is represented as a Number, when it clearly looses precision internally? It's not that I need to represent my alpha values with double precision, I just don't like the design of non-transparent type conversion.

Chris Velevitch | Jun 16th, 2008, 12:18 AM

I believe it's for 2 reasons. Firstly, it's not humanly possible to see the difference between alpha values that differ at the 64th bit, and I don't think current technology can generated it. Secondly, alpha values are usually calculated from some geometric or trigometric expression.

Mark S. Rasmussen | Jun 16th, 2008, 10:26 PM

Chris,

I do not require my alpha values to be precise to multiple decimals, I don't even need decimal precision - as you say, we won't notice anyways. As for the expression math, that may be, but that does not change that the original input ought maintain it's value while the end result might loose precision.

The thing here is that specifying the alpha value as a Number declares a contract. Whatever you input into my alpha property will be of type Number, and hence act as a number. By silently - somehow - converting the internal representation to only 8 bits, we loose precision - which goes against the Number contract.

Now, AS3 does not - to my knowledge - have an 8bit datatype, so that is out of the question. DisplayObject ought to save the original value as a Number and only use their less precise internal value in internal calculations. If I set my value to X, I should get X back - as long as I do not cross the precision boundaries of the specified type, Number.

This is priggishness, I know, but it's important none the less, imho.

v4corg | Jun 7th, 2009, 10:30 AM

to the 8-bit representation: i believe more that the real internally used alpha - value is a simple ubyte (0-255) whichs getter function just "Numbers" it.

sts | Oct 11th, 2009, 3:51 PM

Good work, i like your blog theme, and content ofcourse

hosting | Oct 27th, 2009, 9:15 AM

Can anyone please recommend a training portal covering sales and marketing web seminars?

Dubai Rental | Jun 20th, 2010, 12:21 PM

Wow nice info you have here. I hope this will help a lot of people. I will tell my friends to read this. Thanks!

office chairs | Jul 10th, 2010, 2:50 AM

This ergonomic high back office chair extends the full length of the back, up to the shoulders and includes support for the head and neck. Our chairs are crafted to perfection and designed to the bodies natural shape, you will find complete comfort with its PU leather material and padded arm rests.

The chair is fitted with optimised functions which include gas height adjustment and tilt mechanism, to allow for greater comfort and allowing you to find your ideal position.

Our executive range of office chairs are built to be Safe, to last for years and cannot be beat in any head to head comparison in its class. Easy assemble, a strong nylon base and 360° swivel, top this PU leather, a fantastic executive look.

shoe storage | Aug 9th, 2010, 1:35 PM

Its always good to learn tips like you share for blog posting. As I just started posting comments for blog and facing problem of lots of rejections. I think your suggestion would be helpful for me. I will let you know if its work for me too.

Add comment

After you have posted a comment, an email will be sent to the provided email address. Before your comment is activated, you will have to click the confirmation link within the email.

Name:

Email (only used for validation):

Website (optional):

Message:

Notify me when new comments are added:

Please type the following letters into the box below:  

Post!