More ... | 編集履歴:差分2015/09/09 10:03:58 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 ダウンロード先(外部リンク)] |