/* 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; } } 指数が整数の累乗計算pow