In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

円周率計算

Get Adobe Flash player
by h6k 23 Mar 2010
    Embed
/**
 * Copyright h6k ( http://wonderfl.net/user/h6k )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/xCpW
 */

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFieldAutoSize;
	import flash.utils.getTimer;
	
    public class FlashTest extends Sprite {
    		private var keta:int;
		private var L:int;					// 配列のサイズ
		private var N:Array = new Array(4);	// 項数用
		private var q:Array = new Array(4);	// 計算用
		private var r:Array;
		private var pi:Array;				// 結果用
		
		private var k:uint;					// カウンター用
		private var T:uint;					// タイマー用
		private var flag:Boolean = false;		// スクロール用
		
		private var kfld:TextField = new TextField();
		private var pfld:TextField = new TextField();
		private var tfld:TextField = new TextField();
		
        public function FlashTest() {
            // write as3 code here..
			stage.frameRate = 1000;
			// 配列用意
			var i:int;
			for (i = 0; i < 4; i++) {
				q[i] = new Array(L);
				r = new Array(L);
				pi = new Array(L);
			}
			
			// 桁入力用
			addChild(kfld);
			kfld.x = 10;
			kfld.y = 10;
			kfld.width = 50;
			kfld.height = 20;
			kfld.type = TextFieldType.INPUT;
			kfld.border = true;
			kfld.borderColor = 0;
			kfld.text = "2037";
			
			var fld:TextField = new TextField();
			addChild(fld);
			fld.x = 65;
			fld.y = 10;
			fld.width = 90;
			fld.height = 20;
			//fld.border = true;
			fld.text = "桁 | 式をクリック";
			fld.mouseEnabled = false;
			
			// 結果用
			addChild(pfld);
			pfld.width = pfld.height = 400;
			pfld.x = 10;
			pfld.y = 40;
			pfld.border = true;
			pfld.text = "ロマンという事で(笑)\n\n※ 1949年、世界初(?)のコンピュータENIACでマチンの公式を用いて\n 2037桁を計算するのに70時間掛かったとの事。";
			
			// 時間用
			addChild(tfld);
			tfld.x = 10;
			tfld.y = 440;
			tfld.width = 400;
			tfld.height = 20;
			tfld.autoSize = TextFieldAutoSize.RIGHT;
			tfld.mouseEnabled = false;
			
			// ボタン
			var btn:Array = new Array(3);
			var bfld:Array = new Array(3);
			for (i = 0; i < 3; i++) {
				bfld[i] = new TextField();
				bfld[i].height = 20;
				bfld[i].autoSize = TextFieldAutoSize.LEFT;
				bfld[i].mouseEnabled = false;
				bfld[i].border = true;
				btn[i] = new Sprite();
				btn[i].addChild(bfld[i]);
				btn[i].x = 80 * i + 160;
				btn[i].y = 10;
				btn[i].buttonMode = true;
				btn[i].addEventListener(MouseEvent.CLICK, onMouseClick(i));
				addChild(btn[i]);
			}
			bfld[0].text = "マチンの公式";
			bfld[1].text = "ガウスの公式";
			bfld[2].text = "ストーマーの公式";
			
			// スクロール用
			var scr:Array = new Array(2);
			var ubtn:Array = new Array(2);
			for (i = 0; i < 2; i++) {
				scr[i] = new TextField();
				scr[i].width = scr[i].height = 20;
				scr[i].autoSize = TextFieldAutoSize.CENTER;
				scr[i].mouseEnabled = false;
				scr[i].border = true;
				ubtn[i] = new Sprite();
				ubtn[i].addChild(scr[i]);
				ubtn[i].x = 410;
				ubtn[i].y = 380 * i + 40;
				ubtn[i].buttonMode = true;
				ubtn[i].addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown(i));
				addChild(ubtn[i]);
			}
			scr[0].text = "▲";
			scr[1].text = "▼";
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }
        
        	// マウスが押された
		private function onMouseDown(mode:int):Function {
			return function(e:MouseEvent):void {
				flag = true;
				stage.addEventListener(Event.ENTER_FRAME, onScroll(mode));
			}
		}
		
		// マウスが離された
		private function onMouseUp(e:MouseEvent):void {
			flag = false;
		}
		
		// マウスが押されている間スクロール
		private function onScroll(mode:int):Function {
			return function(e:Event):void {
				if (flag) {
					if (mode == 0) {
						pfld.scrollV--;
					} else {
						pfld.scrollV++;
					}
				} else {
					stage.removeEventListener(Event.ENTER_FRAME, arguments.callee);
				}
			}
		}
		
		// 計算開始
		private function onMouseClick(mode:int):Function {
			return function(e:MouseEvent):void {
				// 桁数取得
				keta = (int)(kfld.text);
				if (keta <= 0) {
					pfld.text = "有効な桁数を入力して下さい。";
					return;
				}
				
				// 必要な配列数
				L = (int)((keta / 4) + 3);
				
				// 初期化
				for (var i:int = 0; i < L; i++) {
					q[0][i] = q[1][i] = r[i] = pi[i] = 0;
					switch(mode) {
						case 2:
							q[3][i] = 0;
						case 1:
							q[2][i] = 0;
					}
				}
				
				// 計算
				k = 1;
				T = getTimer();
				switch(mode) {
					case 0:
						// π = 16arctan(1/5) - 4arctan(1/239)
						N[0] = Math.floor(keta / (2 * Math.log(5) * Math.LOG10E) + 1);
						N[1] = Math.floor(keta / (2 * Math.log(239) * Math.LOG10E) + 1);
						q[0][0] = 16 * 5;
						q[1][0] = 4 * 239;
						stage.addEventListener(Event.ENTER_FRAME, machin);
						break;
					case 1:
						// π = 48arctan(1/18) + 32arctan(1/57) - 20arctan(1/239)
						N[0] = Math.floor(keta / (2 * Math.log(18) * Math.LOG10E) + 1);
						N[1] = Math.floor(keta / (2 * Math.log(57) * Math.LOG10E) + 1);
						N[2] = Math.floor(keta / (2 * Math.log(239) * Math.LOG10E) + 1);
						q[0][0] = 48 * 18;
						q[1][0] = 32 * 57;
						q[2][0] = 20 * 239;
						stage.addEventListener(Event.ENTER_FRAME, gauss);
						break;
					case 2:
						// π = 176arctan(1/57) + 28arctan(1/239) - 48arctan(1/682) + 96arctan(1/12943)
						N[0] = Math.floor(keta / (2 * Math.log(57) * Math.LOG10E) + 1);
						N[1] = Math.floor(keta / (2 * Math.log(239) * Math.LOG10E) + 1);
						N[2] = Math.floor(keta / (2 * Math.log(682) * Math.LOG10E) + 1);
						N[3] = Math.floor(keta / (2 * Math.log(12943) * Math.LOG10E) + 1);
						q[0][0] = 176 * 57;
						q[1][0] = 28 * 239;
						q[2][0] = 48 * 682;
						q[3][0] = 96 * 12943;
						stage.addEventListener(Event.ENTER_FRAME, stormer);
						break;
				}
			}
		}
		
		// 結果表示
		private function result():void {
			tfld.text = (String)((getTimer() - T) / 1000) + " sec";
			
			var str:String = "π = " + pi[0] + ".";
			for (var i:int = 1; i < pi.length - 1; i++) {
				if (i % 14 == 0) { str += "\n"; }
				
				var s:String = (String)(pi[i]);
				switch(s.length) {
					case 1:
						s = "000" + s;
						break;
					case 2:
						s = "00" + s;
						break;
					case 3:
						s = "0" + s;
						break;
				}
				
				if(i * 4 <= keta) {
					str += s + " ";
				} else {
					str += s.substr(0, 4 - (i * 4 - keta));
				}
			}
			pfld.text = str;
		}
		
				// ストーマーの公式
		private function stormer(e:Event):void {
			if(k <= N[3]) {
				q[0] = division(q[0], 57 * 57);
				q[1] = division(q[1], 239 * 239);
				r = addition(q[0], q[1]);
				
				q[2] = division(q[2], 682);
				q[2] = division(q[2], 682);
				r = subtraction(r, q[2]);
				
				q[3] = division(q[3], 12943);
				q[3] = division(q[3], 12943);
				r = addition(r, q[3]);
			} else if(k <= N[2]) {
				q[0] = division(q[0], 57 * 57);
				q[1] = division(q[1], 239 * 239);
				r = addition(q[0], q[1]);
				
				q[2] = division(q[2], 682);
				q[2] = division(q[2], 682);
				r = subtraction(r, q[2]);
			} else if (k <= N[1]) {
				q[0] = division(q[0], 57 * 57);
				q[1] = division(q[1], 239 * 239);
				r = addition(q[0], q[1]);
			} else {
				r = q[0] = division(q[0], 57 * 57);
			}
			
			r = division(r, 2 * k - 1);
			if (k % 2 != 0) {
				pi = addition(pi, r);
			} else {
				pi = subtraction(pi, r);
			}
			
			if (k++ >= N[0]) {
				stage.removeEventListener(Event.ENTER_FRAME, arguments.callee);
				result();
			} else {
				tfld.text = (String)(Math.floor(k / N[0] * 100)) + " %";
			}
		}
		
		// ガウスの公式
		private function gauss(e:Event):void {
			if(k <= N[2]) {
				q[0] = division(q[0], 18 * 18);
				q[1] = division(q[1], 57 * 57);
				q[2] = division(q[2], 239 * 239);
				
				r = addition(q[0], q[1]);
				r = subtraction(r, q[2]);
			} else if (k <= N[1]) {
				q[0] = division(q[0], 18 * 18);
				q[1] = division(q[1], 57 * 57);
				r = addition(q[0], q[1]);
			} else {
				r = q[0] = division(q[0], 18 * 18);
			}
			
			r = division(r, 2 * k - 1);
			if (k % 2 != 0) {
				pi = addition(pi, r);
			} else {
				pi = subtraction(pi, r);
			}
			
			if (k++ >= N[0]) {
				stage.removeEventListener(Event.ENTER_FRAME, arguments.callee);
				result();
			} else {
				tfld.text = (String)(Math.floor(k / N[0] * 100)) + " %";
			}
		}
		
		// マチンの公式
		private function machin(e:Event):void {
			if (k <= N[1]) {
				q[0] = division(q[0], 5 * 5);
				q[1] = division(q[1], 239 * 239);
				r = subtraction(q[0], q[1]);
			} else {
				r = q[0] = division(q[0], 5 * 5);
			}
			
			r = division(r, 2 * k - 1);
			if (k % 2 != 0) {
				pi = addition(pi, r);
			} else {
				pi = subtraction(pi, r);
			}
			
			if (k++ >= N[0]) {
				stage.removeEventListener(Event.ENTER_FRAME, arguments.callee);
				result();
			} else {
				tfld.text = (String)(Math.floor(k / N[0] * 100)) + " %";
			}
		}
		
		// c = a / b;
		private function division(a:Array, b:int):Array {
			var c:Array = new Array(L);
			var surplus:int = 0;
			for (var i:int = 0; i < L; i++) {
				c[i] = Math.floor((a[i] + surplus) / b);	// 小数点以下切捨て
				surplus = ((a[i] + surplus) % b) * 10000;		// 余り
			}
			
			return c;
		}
		
		// c = a - b
		private function subtraction(a:Array, b:Array):Array {
			var c:Array = new Array(L);
			var bollow:int = 0;	// 桁下げ
			for (var i:int = L - 1; i >= 0; i--) {
				c[i] = a[i] - b[i] - bollow;
				if (c[i] >= 0) {
					bollow = 0;
				} else {
					c[i] += 10000;
					bollow = 1;
				}
			}
			
			return c;
		}
		
		// c = a + b
		private function addition(a:Array, b:Array):Array {
			var c:Array = new Array(L);
			var carry:int = 0;	// 桁上げ
			for (var i:int = L - 1; i >= 0; i--) {
				c[i] = a[i] + b[i] + carry;
				if (c[i] < 10000) {
					carry = 0;
				} else {
					c[i] -= 10000;
					carry = 1;
				}
			}
			
			return c;
		}
    }
}