指数が整数の累乗計算pow

by umhr forked from もっと低コストなMath.sin (diff: 223)
Math.pow()を計算するより、指数が20以下の整数なら簡易版関数の方がちょっとだけ早い

けど、結果が微妙すぎ。

これなら、大量に計算する場合であっても、普通にMath.powを使った方がよさそう。


====以下結果例====
◆Math.pow()を計算するより、指数が20以下の整数なら簡易版関数の方がちょっとだけ早い

_a100:109:Math.powで指数100以下
_a50:104:Math.powで指数50以下
_a20:98:Math.powで指数20以下
_a10:95:Math.powで指数10以下
_a5:89:Math.powで指数5以下
_b100:112:簡易関数Mas.powで指数100以下
_b50:102:簡易関数Mas.powで指数50以下
_b20:89:簡易関数Mas.powで指数20以下
_b10:80:簡易関数Mas.powで指数10以下
_b5:81:簡易関数Mas.powで指数5以下
_a99:8:対照用に0を返すだけの関数


試しに10個、Math.powとMas.powで求めた値との比較をする。
0
0
0
0
0
0
0
0
0
0

====以上結果例====




参考
ロシア乗算
http://questionbox.jp.msn.com/qa3609014.html
指数が有理数の場合 
http://w3e.kanazawa-it.ac.jp/math/category/sisuu-taisuu/ruijyou/henkan-tex.cgi?size=3&target=/math/category/sisuu-taisuu/ruijyou/yuurisuu-no-sisuu.html

♥0 | Line 164 | Modified 2009-03-22 14:04:02 | MIT License
play

ActionScript3 source code

/**
 * Copyright umhr ( http://wonderfl.net/user/umhr )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7KD2
 */

/*
Math.pow()を計算するより、指数が20以下の整数なら簡易版関数の方がちょっとだけ早い

けど、結果が微妙すぎ。

これなら、大量に計算する場合であっても、普通にMath.powを使った方がよさそう。


====以下結果例====
◆Math.pow()を計算するより、指数が20以下の整数なら簡易版関数の方がちょっとだけ早い

_a100:109:Math.powで指数100以下
_a50:104:Math.powで指数50以下
_a20:98:Math.powで指数20以下
_a10:95:Math.powで指数10以下
_a5:89:Math.powで指数5以下
_b100:112:簡易関数Mas.powで指数100以下
_b50:102:簡易関数Mas.powで指数50以下
_b20:89:簡易関数Mas.powで指数20以下
_b10:80:簡易関数Mas.powで指数10以下
_b5:81:簡易関数Mas.powで指数5以下
_a99:8:対照用に0を返すだけの関数


試しに10個、Math.powとMas.powで求めた値との比較をする。
0
0
0
0
0
0
0
0
0
0

====以上結果例====




参考
ロシア乗算
http://questionbox.jp.msn.com/qa3609014.html
指数が有理数の場合 
http://w3e.kanazawa-it.ac.jp/math/category/sisuu-taisuu/ruijyou/henkan-tex.cgi?size=3&target=/math/category/sisuu-taisuu/ruijyou/yuurisuu-no-sisuu.html

*/
package {
	import flash.display.Sprite;
	import flash.geom.Vector3D;
	import flash.text.TextField;
	public class Main extends Sprite {
		public var ran0:Vector.<Number>=new Vector.<Number>(10000000,true);
		public var ran100:Vector.<Number>=new Vector.<Number>(10000000,true);
		public var ran50:Vector.<Number>=new Vector.<Number>(10000000,true);
		public var ran20:Vector.<Number>=new Vector.<Number>(10000000,true);
		public var ran10:Vector.<Number>=new Vector.<Number>(10000000,true);
		public var ran5:Vector.<Number>=new Vector.<Number>(10000000,true);
		private var len:int=1024*1024+1;
		private const PI2:Number=Math.PI*2;
		private var sqrtTable:Vector.<Number>=new Vector.<Number>(len,true);
		public function Main():void {
			var _str:String = new String();
			_str+="◆Math.pow()を計算するより、指数が20以下の整数なら簡易版関数の方がちょっとだけ早い\n\n";

			for (var j:int=0; j<10000000; j++) {
				ran0[j]=Math.random()*100;
				ran100[j]=Math.floor(Math.random()*100);
				ran50[j]=Math.floor(Math.random()*50);
				ran20[j]=Math.floor(Math.random()*20);
				ran10[j]=Math.floor(Math.random()*10);
				ran5[j]=Math.floor(Math.random()*5);
			}

			benchMarkj(_a99);

			_str+="_a100:"+benchMarkj(_a100)+":Math.powで指数100以下\n";
			_str+="_a50:"+benchMarkj(_a50)+":Math.powで指数50以下\n";
			_str+="_a20:"+benchMarkj(_a20)+":Math.powで指数20以下\n";
			_str+="_a10:"+benchMarkj(_a10)+":Math.powで指数10以下\n";
			_str+="_a5:"+benchMarkj(_a5)+":Math.powで指数5以下\n";
			_str+="_b100:"+benchMarkj(_b100)+":簡易関数Mas.powで指数100以下\n";
			_str+="_b50:"+benchMarkj(_b50)+":簡易関数Mas.powで指数50以下\n";
			_str+="_b20:"+benchMarkj(_b20)+":簡易関数Mas.powで指数20以下\n";
			_str+="_b10:"+benchMarkj(_b10)+":簡易関数Mas.powで指数10以下\n";
			_str+="_b5:"+benchMarkj(_b5)+":簡易関数Mas.powで指数5以下\n";
			_str+="_a99:"+benchMarkj(_a99)+":対照用に0を返すだけの関数\n\n\n";

			_str+="試しに10個、Math.powとMas.powで求めた値との比較をする。\n";

			for (j=0; j<10; j++) {
				var k:int=Math.random()*len;
				_str += (Math.pow(ran0[j],ran20[j]) - Mas.pow(ran0[j],ran20[j]))+"\n";
			}

			var text_field:TextField = new TextField();
			text_field.width=stage.stageWidth;
			text_field.height=stage.stageHeight;
			stage.addChild(text_field);
			text_field.text=_str;




		}

		//100万回関数を実行して、かかった時間を返す
		private function benchMarkj(_fn:Function):int {
			var time:Number = (new Date()).getTime();
			_fn(1000000);
			return (new Date()).getTime() - time;
		}

		private function _a100(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Math.pow(ran0[i],ran100[i]);
			}
		}

		private function _a50(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Math.pow(ran0[i],ran50[i]);
			}
		}
		private function _a20(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Math.pow(ran0[i],ran20[i]);
			}
		}
		private function _a10(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Math.pow(ran0[i],ran10[i]);
			}
		}
		private function _a5(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Math.pow(ran0[i],ran5[i]);
			}
		}

		private function _b100(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Mas.pow(ran0[i],ran100[i]);
			}
		}

		private function _b50(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Mas.pow(ran0[i],ran50[i]);
			}
		}
		private function _b10(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Mas.pow(ran0[i],ran10[i]);
			}
		}
		private function _b20(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Mas.pow(ran0[i],ran20[i]);
			}
		}
		private function _b5(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				Mas.pow(ran0[i],ran10[i]);
			}
		}

		private function _a99(n:uint):void {
			for (var i:int = 0; i < n; i++) {
				zero();
			}
		}
		private function zero():Number {
			return 0;
		}
	}
}

import flash.display.Sprite;
class Mas extends Sprite {
	public static function pow(n:Number,p:int):Number {
		//指数(p)が整数の場合のみ有効
		var ans:Number=1;
		if (p<0) {
			//p*=-1;
			p>>>0;
			n=1/n;
		}
		//var ans2:Number = Math.pow(n,p%1);
		for (null; p>5; p >>= 1) {
			if (p&1) {
				//奇数の場合のみかける
				ans*=n;
			}
			n*=n;
		}
		switch (p) {
			case 1:
				ans *= n;
				break;
			case 2:
				ans *= n*n;
				break;
			case 3:
				ans *= n;
				ans *= n*n;
				break;
			case 4:
				n *= n;
				ans *= n*n;
				break;
			case 5:
				ans *= n;
				n *= n;
				ans *= n*n;
				break;
		}

		//trace(ans,ans2,ans*ans2)
		return ans;
	}

	public static function round(n:Number):Number {
		n+=0.5;
		return n>0?n>>0:--n>>0;
	}

	public static function floor(n:Number):Number {
		return n>0?n>>0:--n>>0;
	}

	public static function ceil(n:Number):Number {
		return n>0?++n>>0:n>>0;
	}

	public static function abs(n:Number):Number {
		return n>0?n:-n;
	}
}