巨大な数値の計算
投稿者:
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
コメントする
コメントするには、ログインする必要があります。
コメント一覧
関数のボリューム凄いですね、、、(w