More ... | 編集履歴:過去のバージョン2015/09/09 09:47:32 JST時点での数式の文字列を計算するモジュールの内容数式の文字列を計算するモジュール {{{ #module mojikeisan //数式の文字列を計算するモジュール(修正版) //使い方 keisan(数式,計算方法[0=整数型,1=実数型,2=簡易数式チェック]) //keisan(p1,p2) //p1=strings : 数式 //p2=0~2(0) : 計算方法( 0整数型,1=実数型,2=簡易数式チェック) //整数型の場合返し値は整数型(int) //実数型の場合返し値は実数型(double) //簡易数式チェックの場合 0=数式はおかしい 1=数式は正しい (注意: ()+-*/以外の文字のチェックはしません) //計算方法に0から2以外の数を入れた場合整数型で計算します //NYSL 0.9982で公開します //ライセンス文 (http://www.kmonos.net/nysl/) #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+4,4 }else{ sdim stmp,nagasa+4,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=='/' & peek(sushiki,I+1)=='0'{ K=-1 : _break } 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)=='/' { if P==0 : K=-1 : _break 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 K==-1 : sushiki="0" : _break 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 if N+M>=nagasa+4: N=nagasa+3-M//追加 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 { if peek(sushiki,I-2)=='+'{ 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) } }else{ if peek(sushiki,I-2)=='-'{ 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) } } } }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) mes keisan("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890") mes keisan("1234567890123456789012345678901234567890123456789012345678901") mes keisan("1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1",1)+1 mes 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 mes keisan("5/0") mes keisan("5/(4-4)+1") mes keisan("5*(7-7)+1") }}} [https://aa38020e42f53ca54e166915354734af1f102cbd.googledrive.com/host/0B9vewWZYDiXefmNjRWZCb1FrUmpab3o2dk5nTXRkRFdGTXFqTWZjNExVTm41OHUwWFdRUG8/apps/calculat.txt ダウンロード先(外部リンク)] |