Overcoming rounding errors (code)

September 25, 2008 at 7:43 pm 1 comment

package { // Decimal.as  by Daniel Freeman http://www.e2easy.co.cc

	public class Decimal {

		private var mantissa:int;
		private var exponent:int;
		private var fixed:Boolean=false;

		public function Decimal(mantissa:int=0,exponent:int=0) {
			this.mantissa=mantissa;
			this.exponent=exponent;
		}

		public function convert(float:Number):void {
			var strng:String=float.toString();
			var pnt:int=strng.indexOf('.');

			if (pnt<0) {
				mantissa=float;
				exponent=0;
				normalise();
			} else {
				exponent=pnt-strng.length+1;
				mantissa=Math.round(float*Math.pow(10,-exponent));
			}
			fixed=false;
		}

		public function converttoprecision(float:Number,exponent:int):void {			
			this.exponent=exponent
			mantissa=Math.round(float*Math.pow(10,-exponent));
			fixed=true;
		}

		private function normalise():void {
			if (!fixed && mantissa!=0) {
				while (mantissa % 10 == 0) {
				mantissa=mantissa/10;
				exponent++;
				}
			}
		}

		public function add(num:Decimal,minus:Boolean=false):Decimal {
			var ret:Decimal=new Decimal();
			var m0:int=mantissa;
			var m1:int=num.mantissa;
			var sum:int;

			if (exponent<num.exponent) {
				ret.exponent=exponent;
				m1=m1*Math.pow(10,num.exponent-exponent);
			} else if (exponent>num.exponent) {
				ret.exponent=num.exponent;
				m0=m0*Math.pow(10,exponent-num.exponent);
			} else ret.exponent=exponent;
			ret.mantissa=minus ? m0-m1 : m0+m1;
			ret.fixed=fixed && num.fixed;
			ret.normalise();
			return ret;
		}

		public function subtract(num:Decimal):Decimal {
			return add(num,true);
		}		

		public function multiply(num:Decimal):Decimal {
			var ret:Decimal=new Decimal(mantissa*num.mantissa,exponent+num.exponent);

			ret.fixed=fixed && num.fixed;
			ret.normalise();
			return ret;
		}

		public function toString():String {
			var ret:String;
			var sign=mantissa<0;
			var pos:int,i:int;

			if (sign) mantissa=-mantissa;
			ret=mantissa.toString();
			if (exponent<0) {
				pos=ret.length+exponent;
				if (pos<0) {
					for (i=0;i<-pos;i++) ret='0'+ret;
					ret='0.'+ret;
				} else {
					ret=ret.substring(0,pos)+'.'+ret.substring(pos,ret.length);
					if (pos==0) ret='0'+ret;
				}
			} else if (exponent>0) {
				for (i=0;i<exponent;i++) ret+='0';
			}
			if (sign) {ret='-'+ret;mantissa=-mantissa}
			return ret;
		}

	}
}
Advertisements

Entry filed under: Adobe AIR.

Undo and redo Overcoming rounding errors

1 Comment Add your own

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


  RSS feed          View Daniel Freeman's LinkedIn profileView my profile

Add to Technorati Favorites

September 2008
M T W T F S S
    Oct »
1234567
891011121314
15161718192021
22232425262728
2930  

%d bloggers like this: