More ... | Edit History:DiffChanges of 数式の文字列を計算するモジュール between Epoch and 2015/09/09 09:43:01 JST
+ {{{ + #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 ダウンロード先(外部リンク)] |