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

Edit History:Diff

Changes of 数式の文字列を計算するモジュール between Epoch and 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 ダウンロード先(外部リンク)]