巨大な数値の計算
投稿者: cfm_ 投稿日:2016/03/30 16:44
参考にしたサイト
http://7ujm.net/index.html
数値の圧縮などで、大きな数値を計算したい方へ。
最初にmath_setSizeで何桁まで計算するか指定する必要があります。
正確には、奇数を指定した場合+1されます(5を渡すと6が設定される)
正しい答えが123456のとき、6桁以上を指定する必要があります。
基本的には、数をかなり大きくしておけば大丈夫だと思います。
関数
ツイート
http://7ujm.net/index.html
数値の圧縮などで、大きな数値を計算したい方へ。
#====サンプル==== # 300桁まで計算する math_setSize(300) #足し算 =a+b speak(math_add(3456535300,55515561155)) #引き算 =a-b speak(math_sub(3003,555656455)) #掛け算 =a*b speak(math_mul(30644566651666130,55445556661656)) # 除算の商 =floor(a/b) speak(math_div(304340,23631)) # 剰余 =a%b speak(math_mod(304340,23631)) #計算結果 #58972096455 #-555653452 #1699105056656848296693084911280 #12 #20768 #====サンプル2==== math_setSize(300) x=1 n=500 while n>0 x=math_mul(x,2) n=n-1 end speak(x) #計算結果 #3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589376
最初にmath_setSizeで何桁まで計算するか指定する必要があります。
正確には、奇数を指定した場合+1されます(5を渡すと6が設定される)
正しい答えが123456のとき、6桁以上を指定する必要があります。
基本的には、数をかなり大きくしておけば大丈夫だと思います。
関数
def cmp(ar,ar1) i=getVariable("math_size")-1 while i>=0 if ar[i]<ar1[i] then return -1;end if ar[i]>ar1[i] then return 1;end i=i-1 end return 0 end def cmp0(ar) i=getVariable("math_size")-1 while i>=0 if ar[i]<0 then return -1;end if ar[i]>0 then return 1;end i=i-1 end return 0 end def floor2(num) if num>0 then return floor(num);else return floor(num)+1;end end def r_shift(ar) ar[0]=ar[0]/10 i=1 while i<getVariable("math_size") pos=ar[i] ar[i-1]=ar[i-1]+((ar[i]%10)*10) ar[i]=floor(ar[i]/10) i=i+1 end end def l_shift(ar) i=getVariable("math_size")-1 while i>=0 ar[i+1]=ar[i+1]+floor(ar[i]/10) ar[i]=(ar[i]*10)%100 i=i-1 end end def turn(ar) i=0 while i<getVariable("math_size") ar[i]=-ar[i] i=i+1 end end def turn2(ar) ar2=createArray() i=0 while i<getVariable("math_size") ar2[i]=-ar[i] i=i+1 end return ar2 end def d02(num) x=toNumber(num) if x<10 return "0"+toString(x) else return toString(x) end end def getNumArray(num) ar=createArray() if num<0 then nu=splitString(toString(-num), "") len=getArrayLength(nu) i=0 while i<getVariable("math_size") if len==i*2+1 ar[i]=-toNumber(nu[len-i*2-1]) elsif len>i*2+1 ar[i]=-toNumber(nu[len-i*2-2])*10-toNumber(nu[len-i*2-1]) else ar[i]=0 end i=i+1 end else nu=splitString(toString(num), "") len=getArrayLength(nu) i=0 while i<getVariable("math_size") if len==i*2+1 ar[i]=toNumber(nu[len-i*2-1]) elsif len>i*2+1 ar[i]=toNumber(nu[len-i*2-2])*10+toNumber(nu[len-i*2-1]) else ar[i]=0 end i=i+1 end end return ar end def ar_str(ar) start_flag=false p_flag=cmp0(ar) if p_flag==0 then return "0" else if p_flag==-1 s="-" turn(ar) else s="" end i=getVariable("math_size")-1 while i>=0 if ar[i]!=0 || start_flag if !start_flag s=s+toString(ar[i]) start_flag=true else s=s+toString(d02(ar[i])) end end i=i-1 end if p_flag==-1 then turn(ar);end return s end end def math_setSize(size) setVariable("math_size",floor(size/2)+1) end #加算 def math_add(a,b) ar=getNumArray(a) ar2=getNumArray(b) ar3=createArray() i=0 while i<getVariable("math_size") ar3[i]=ar[i]+ar2[i] i=i+1 end i=0 while i<getVariable("math_size") if ar3[i]>99 ar3[i]=ar3[i]-100 ar3[i+1]=ar3[i+1]+1 elsif ar3[i]<-99 ar3[i]=ar3[i]+100 ar3[i+1]=ar3[i+1]-1 end i=i+1 end p_flag=cmp0(ar3) if p_flag!=0 i=0 while i<getVariable("math_size") if p_flag>0 if 0>ar3[i] ar3[i+1]=ar3[i+1]-1 ar3[i]=ar3[i]+100 end else if 0<ar3[i] ar3[i+1]=ar3[i+1]+1 ar3[i]=ar3[i]-100 end end i=i+1 end end return ar_str(ar3) end #配列を加算 def math_addAr(ar,ar2) ar3=createArray() i=0 while i<getVariable("math_size") ar3[i]=ar[i]+ar2[i] i=i+1 end i=0 while i<getVariable("math_size") if ar3[i]>99 ar3[i]=ar3[i]-100 ar3[i+1]=ar3[i+1]+1 elsif ar3[i]<-99 ar3[i]=ar3[i]+100 ar3[i+1]=ar3[i+1]-1 end i=i+1 end p_flag=cmp0(ar3) if p_flag!=0 i=0 while i<getVariable("math_size") if p_flag>0 if 0>ar3[i] ar3[i+1]=ar3[i+1]-1 ar3[i]=ar3[i]+100 end else if 0<ar3[i] ar3[i+1]=ar3[i+1]+1 ar3[i]=ar3[i]-100 end end i=i+1 end end return ar3 end #減算 def math_sub(a,b) return math_add(a,-b) end #配列を減算 def math_subAr(ar,ar2) return math_addAr(ar,turn2(ar2)) end #乗算 def math_mul(a,b) ar=getNumArray(a) ar2=getNumArray(b) ar3=createArray() i=0 while i<getVariable("math_size") ar3[i]=0 i=i+1 end i=0 while i<getVariable("math_size") if ar2[i]!=0 j=0 while j<getVariable("math_size") ar3[j+i]=ar3[j+i]+ar[j]*ar2[i] #3桁目を繰り上げる if ar3[j+i]>99 || ar3[j+i]<-99 pos=ar3[j+i]/100 ar3[j+i]=ar3[j+i]%100 #ar3[j+i]-(pos*100) ar3[j+1+i]=ar3[j+1+i]+floor2(pos) end j=j+1 end end i=i+1 end return ar_str(ar3) end #除算 def math_div(a,b) ar=getNumArray(a) ar2=getNumArray(b) ar3=createArray() pos=0 i=0 while i<getVariable("math_size") ar3[i]=0 i=i+1 end div_flag=cmp0(ar)# 被除数の符号フラグ met_flag=cmp0(ar2)# 法の符号フラグ if !div_flag || !met_flag then return 0;end #法、被除数のどちらかが0であるため計算中止 if -1==div_flag then turn(ar);end #被除数が負数であるため正数にする if -1==met_flag then turn(ar2);end #法が負数であるため正数にする while cmp(ar,ar2)==1 && floor(ar2[getVariable("math_size")-1]/10)==0 pos=pos+1 l_shift(ar2) end while pos>=0 if cmp(ar,ar2)>=0 ar=math_subAr(ar,ar2) if (pos%2)!=0 then ar3[pos/2]=ar3[pos/2]+10;else ar3[pos/2]=ar3[pos/2]+1;end else if pos!=0 then r_shift(ar2);end pos=pos-1 end end if -1==div_flag then turn(ar);end #被除数の符号を戻す if div_flag!=met_flag then turn(ar3);end #被除数と法の符号が違うため、答えをマイナスにする return ar_str(ar3) end #剰余 def math_mod(a,b) ar=getNumArray(a) ar2=getNumArray(b) pos=0 div_flag=cmp0(ar)# 被除数の符号フラグ met_flag=cmp0(ar2)# 法の符号フラグ if !div_flag || !met_flag then return 0;end #法、被除数のどちらかが0であるため計算中止 if -1==div_flag then turn(ar);end #被除数が負数であるため正数にする if -1==met_flag then turn(ar2);end #法が負数であるため正数にする while cmp(ar,ar2)==1 && floor(ar2[getVariable("math_size")-1]/10)==0 pos=pos+1 l_shift(ar2) end while pos>=0 if cmp(ar,ar2)>=0 ar=math_subAr(ar,ar2) else if pos!=0 then r_shift(ar2);end pos=pos-1 end end if -1==div_flag then turn(ar);end #被除数の符号を戻す return ar_str(ar) end
コメントする
コメントするには、ログインする必要があります。
コメント一覧
aoihikawa(投稿日:2016/03/30 21:37,
履歴)
関数のボリューム凄いですね、、、(w