[Top Page][All Pages][Recent Changes]

Edit History:Diff

Changes of 数式の文字列を計算するモジュール since 2015/09/09 09:43:01 JST

  • + added lines
  • - deleted lines

Return to the edit history

- {{{
- #module mojikeisan
- 	//数式の文字列を計算するモジュール
- 	//使い方 keisan(数式,計算方法[0=整数型,1=実数型,2=簡易数式チェック])
- 	//整数型の場合返し値は整数型(int)
- 	//実数型の場合返し値は実数型(double)
- 	//簡易数式チェックの場合 0=数式はおかしい 1=数式は正しい (注意: ()+-*/以外の文字のチェックはしません)
- 	//計算方法に0から2以外の数を入れた場合整数型で計算します
- 
- 	#define I tmp.0
- 	#define J tmp.1
- 	#define K tmp.2
- 	#define L tmp.3
- 	#define M tmp.4
- 	#define N tmp.5
- 	#define O tmp.6
- 	#define P tmp.7
- 	#define Q tmp.8
- 	#define R tmp.9
- 	#define S tmp.10
- 	#define T tmp.11
- 
- 	#defcfunc keisan str p1 , int atype , local sushiki , local nagasa , local stmp , local tmp , local btype , local dtmp//ローカル変数はつけ外ししてください
- 		sushiki=p1
- 		nagasa=strlen(sushiki)
- 		btype=atype
- 		if atype<0 | atype>2 : btype=0
- 		if btype==1{
- 			ddim dtmp,5
- 			sdim stmp,nagasa*8+1,4
- 		}else{
- 			sdim stmp,nagasa+1,4
- 		}
- 		dim tmp,12
- 		I=0
- 		K=0
- 		while I<nagasa//数式チェック
- 			J=peek(sushiki,I)
- 			if J=='(' : K+=1
- 			if J==')' : K-=1{
- 			if I<nagasa-1
- 				if J=='(' | J=='+' | J=='-' | J=='/' | J=='*'{
- 					J=peek(sushiki,I+1)
- 					if J=='+' | J=='-' | J=='/' | J=='*'{
- 						K=-1 : _break
- 					}
- 					J=peek(sushiki,I)
- 				}
- 			}
- 			if I==0{
- 				if J==')' | J=='+' | J=='-' | J=='/' | J=='*'{
- 					K=-1 : _break
- 				}
- 			}
- 			if I==nagasa-1{
- 				if J=='(' | J=='+' | J=='-' | J=='/' | J=='*'{
- 					K=-1 : _break
- 				}
- 			}
- 			I++
- 		wend
- 
- 		if K!=0 : return 0//かっこの数が合わない場合
- 		if btype==2 : return 1
- 
- 		while//計算
- 
- 			if peek(sushiki,0)=='-' | peek(sushiki,0)==0 : _break
- 
- 			//かっこの中身を取り出し
- 			I=0
- 			J=instr(sushiki,I,"(") 
- 			while J!=-1 & J<instr(sushiki,I,")")
- 				I+=(J+1)
- 				J=instr(sushiki,I,"(") 
- 			wend
- 			J=instr(sushiki,I,")")
- 			if J==-1 : J=strlen(sushiki)-I
- 
- 			poke stmp.0,J,0
- 			memcpy stmp.0,sushiki,J,,I
- 
- 			if J+I<nagasa {
- 				poke stmp.1,nagasa-(J+I+1),0
- 				memcpy stmp.1,sushiki,nagasa-(J+I+1),,J+I+1
- 			}else{
- 				poke stmp.1,0,0
- 			}
- 
- 			if I>0 : poke sushiki,I-1,0 : else : poke sushiki,0,0
- 
- 			//中身を計算
- 			T=J
- 			while instr(stmp.0,0,"*")!=-1 | instr(stmp.0,0,"/")!=-1//掛け算と割り算を先に計算
- 				//前から計算
- 				K=0
- 				L=0
- 				while L!=-1
- 					K+=(L+1)
- 					L=instr(stmp.0,K,"+")
- 					M=instr(stmp.0,K,"/")
- 					N=instr(stmp.0,K,"*")
- 					if N==-1 : N=J
- 					if M==-1 : M=J
- 					if L==-1 | L>N | L>M : L=instr(stmp.0,K,"-")
- 					if L==-1 | L>N | L>M : L=-1
- 				wend
- 				if K==1 : K=0
- 				L=instr(stmp.0,K,"/")
- 				M=instr(stmp.0,K,"*")
- 				if M==-1 : M=J-K
- 				if L>M | L==-1 : L=M
- 				if L==-1 : L=J-K
- 
- 				poke stmp.2,L,0
- 				memcpy stmp.2,stmp.0,L,,K
- 				if btype==0 : O=int(stmp.2)
- 				if btype==1 : dtmp.0=double(stmp.2)
- 
- 				M=instr(stmp.0,K+L,"+")
- 				S=instr(stmp.0,K+L+1,"*")+1
- 				R=instr(stmp.0,K+L+1,"/")+1
- 				T=instr(stmp.0,K+L,"-")
- 				if S==0 : S=J-(K+L)
- 				if R==0 : R=J-(K+L)
- 				if T==-1 : T=J-(K+L)
- 
- 				if M==-1 | M>T : M=T
- 				if M==-1 | M>S : M=S
- 				if M==-1 | M>R : M=R
- 				if M==-1:M=J-(K+L)
- 
- 				poke stmp.2,M-1,0
- 				memcpy stmp.2,stmp.0,M-1,,K+L+1
- 				if btype==0 : P=int(stmp.2)
- 				if btype==1 : dtmp.1=double(stmp.2)
- 
- 				if btype==0{
- 					if peek(stmp.0,K+L)=='*' : O*=P
- 					if peek(stmp.0,K+L)=='/' : O/=P
- 				}
- 				if btype==1{
- 					if peek(stmp.0,K+L)=='*' : dtmp.0*=dtmp.1
- 					if peek(stmp.0,K+L)=='/' : dtmp.0/=dtmp.1
- 				}
- 	
- 				poke stmp.3,J-(M+K+L)
- 				memcpy stmp.3,stmp.0,J-(M+K+L),,M+K+L
- 
- 				poke stmp.0,K,0
- 				if btype==0 : stmp.0+=str(O)+stmp.3
- 				if btype==1 : stmp.0+=str(dtmp.0)+stmp.3
- 				J=strlen(stmp.0)
- 			wend
- 
- 			if instr(stmp.0,0,"+")==-1 & instr(stmp.0,0,"-")==-1{
- 				poke stmp.0,J,"+0"
- 				J+=2
- 				poke stmp.0,J,0
- 			}
- 
- 			while instr(stmp.0,0,"+")!=-1 | instr(stmp.0,0,"-")!=-1//足し算と引き算を後に計算
- 				//後ろから計算
- 				K=-1
- 				L=0
- 				while L!=-1
- 					K+=(L+1)
- 					L=instr(stmp.0,K,"+")
- 					N=instr(stmp.0,K,"-")
- 					if N==-1 : N=J
- 					if L==-1 | L>N : L=N
- 					if L==J : L=-1
- 				wend
- 
- 				if K==1 : K=0
- 				L=instr(stmp.0,K,"+")
- 				M=instr(stmp.0,K,"-")
- 				if M==-1 : M=J-K
- 				if L>M | L==-1 : L=M
- 				if L==-1 : L=J-K
- 
- 				poke stmp.2,L,0
- 				memcpy stmp.2,stmp.0,L,,K
- 
- 				if btype==1 : dtmp.0=double(stmp.2)
- 				if btype==0 : O=int(stmp.2)
- 
- 
- 				M=0
- 				S=-1
- 				N=0
- 				while N!=-1
- 					S+=(N+1)
- 					N=instr(stmp.0,S,"+")
- 					Q=instr(stmp.0,S,"-")
- 					if Q==-1 : Q=K-1
- 					if N==-1 | N>Q : N=Q
- 					if N==K-1 : _break
- 					//N=R
- 					M=S
- 				wend
- 
- 				poke stmp.2,N,0
- 				memcpy stmp.2,stmp.0,N,,M
- 
- 				if btype==1 : dtmp.1=double(stmp.2)
- 				if btype==0 : P=int(stmp.2)
- 
- 				if btype==0{
- 					if M>0 : if peek(stmp.0,M-1)=='-' : P=-P
- 					if peek(stmp.0,K-1)=='+' : Q=P+O
- 					if peek(stmp.0,K-1)=='-' : Q=P-O
- 				}
- 				if btype==1{
- 					if M>0 : if peek(stmp.0,M-1)=='-' : dtmp.1=-dtmp.1
- 					if peek(stmp.0,K-1)=='+' : dtmp.2=dtmp.1+dtmp.0
- 					if peek(stmp.0,K-1)=='-' : dtmp.2=dtmp.1-dtmp.0
- 				}
- 
- 
- 				poke stmp.3,J-(K+L),0
- 				memcpy stmp.3,stmp.0,J-(K+L),,K+L
- 
- 				if btype==0{
- 					if Q>0 {
- 						poke stmp.0,M,0
- 					}else{
- 						if M>0 : poke stmp.0,M-1,0 : else : poke stmp.0,0,0
- 					}
- 					stmp.0+=str(Q)+stmp.3
- 				}
- 				if btype==1{
- 					if dtmp.2>0 {
- 						poke stmp.0,M,0
- 					}else{
- 						if M>0 : poke stmp.0,M-1,0 : else : poke stmp.0,0,0
- 					}
- 					stmp.0+=str(dtmp.2)+stmp.3
- 				}
- 				J=strlen(stmp.0)
- 
- 				J=strlen(stmp.0)
- 				if peek(stmp.0,0)=='-'{
- 					if I>1 {
- 						switch peek(sushiki,I-2)
- 						case '+'
- 							poke sushiki,I-2,0
- 							I--
- 							nagasa=(nagasa-(T+I+1))+(J)+(I-1)
- 							memcpy sushiki,stmp.0,J,I-1
- 							if peek(stmp.1,0)!=0 {
- 								memcpy sushiki,stmp.1,(nagasa-(T+I+1)),(J)+(I-1)
- 							}else{
- 								nagasa=(J)+(I-1)
- 							}
- 							swbreak
- 						case '-'
- 							poke sushiki,I-2,0
- 							I--
- 							nagasa=(nagasa-(T+I+1))+(J)+(I-1)
- 							memcpy sushiki,stmp.0,J,I-1
- 							poke sushiki,I-1,'+'
- 							if peek(stmp.1,0)!=0 {
- 								memcpy sushiki,stmp.1,(nagasa-(T+I+1)),(J)+(I-1)
- 							}else{
- 								nagasa=(J)+(I-1)
- 							}
- 							swbreak
- 						swend
- 					}else{
- 						nagasa=(nagasa-(T+I+1))+(J)
- 						memcpy sushiki,stmp.0,J
- 						if peek(stmp.1,0)!=0{
- 							memcpy sushiki,stmp.1,(nagasa-(T+I+1)),J
- 						}else{
- 							nagasa=J
- 						}
- 					}
- 					poke sushiki,nagasa,0
- 					_break
- 				}
- 				if instr(stmp.0,0,"+")==-1 & instr(stmp.0,0,"-")==-1{
- 					R=nagasa
- 					if I>0 : I--
- 					nagasa=(nagasa-(T+I+1))+J+I
- 					memcpy sushiki,stmp.0,J,I
- 					if peek(stmp.1,0)!=0{
- 						memcpy sushiki,stmp.1,(R-(T+I+1)),J+I
- 					}else{
- 						nagasa=J+I
- 					}
- 					poke sushiki,nagasa,0
- 					_break
- 				}
- 			wend
- 
- 			if peek(sushiki,0)==0 {
- 				memcpy sushiki,stmp.0,J : nagasa=J
- 				if peek(stmp.1,0)!=0{
- 					memcpy sushiki,stmp.1,(nagasa-(T+I+1)),J
- 					nagasa+=(nagasa-(T+I+1))
- 				}
- 				poke sushiki,nagasa,0
- 			}
- 
- 			if instr(sushiki,0,"(")==-1 & instr(sushiki,0,")")==-1{
- 				if instr(sushiki,0,"+")==-1 & instr(sushiki,0,"-")==-1{
- 					if instr(sushiki,0,"*")==-1 & instr(sushiki,0,"/")==-1{
- 						_break
- 					}
- 				}
- 			}
- 		wend
- 		if btype==0 : return int(sushiki)
- 		if btype==1 : return double(sushiki)
- 
- #global
- //サンプル(数字は適当)
- a=keisan("1000+10+(1+(1-42/21+6*1*3/2-820))")+1
- mes a
- mes keisan("")
- mes keisan("4+5*2-1/2")//掛け算割り算は優先
- mes keisan("17+0")
- mes keisan("(7+1)")
- mes keisan("1+(4)")
- mes keisan("((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((45))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))+1")//100重かっこ
- mes keisan(")+3")//エラー処理
- mes keisan("12+3(",2)//エラーチェック
- mes keisan("1+6",2)//エラーチェック
- mes keisan("1+7",6)//エラーチェック
- mes keisan("1/3",1)//実数計算
- mes keisan("1-(1-2)",1)
- }}}
- [https://aa38020e42f53ca54e166915354734af1f102cbd.googledrive.com/host/0B9vewWZYDiXefmNjRWZCb1FrUmpab3o2dk5nTXRkRFdGTXFqTWZjNExVTm41OHUwWFdRUG8/apps/calculat.txt ダウンロード先(外部リンク)]