Stackoverflow的新功能,所以請指出任何我可以做的事情來提高我的問題的質量。替代long以避免溢出斐波那契數字
所以我的代碼做的(或者更確切地說希望做的)是計算巨大的斐波納契數字,以相當大的模數m。爲了使算法更有效率,我使用了pisano periods。從本質上說,我計算的米的皮薩諾週期,然後進行其餘的計算通過使用下面的關係更容易:
的的Ñ個斐波那契數(模米)的餘數是等於所述ķ個Fibonacci數(模米),使得ķ = ñ%p的其餘部分,其中p是皮薩諾時期米。
爲了計算Pisano的期間,我使用下面的屬性:
如果當前的Fib%米 = 0,並且所有的FIB的直到現在%的總和米 = 0 ,那麼當前Fib的指數是m的pisano期間。 (注意指數必須大於0)
但是我遇到了這個問題:爲了計算pisano時間,我必須計算連續的斐波納契數。當需要計算的斐波那契數量變得非常大時,例如100 000,這個問題就出現了。然後數據類型溢出。
據我所知,任何計算pisano時期的努力都需要計算斐波納契的時間,所以唯一的解決方案似乎是用其他東西替代long。如果有人對這個替代品有什麼建議,我將不勝感激。
import java.util.*;
public class FibHuge {
public static void main (String [] args) {
Scanner in = new Scanner (System.in);
long num = in.nextLong();
long mod = in.nextLong();
System.out.println (getMod(num, mod));
}
private static int getMod (long num, long mod) {
Period per = new Period();
long period = per.getPeriod (mod);
int newFibNum = (int)(num % period);
num = (num % mod);
Integer ia[] = new Integer [per.al.size()];
ia = per.al.toArray (ia);
return ia[newFibNum];
}
}
class Period {
ArrayList <Long> al;
long FNum;
long SNum;
Period() {
al = new ArrayList <Long>();
FNum = 0;
SNum = 1;
}
private long getFib (long first, long second){
return first + second;
}
long getPeriod (long mod){
boolean bool = true;
long fibcount = 0;
long currentmod = 0;
long fib = 0;
long sum = 0;
while (bool){
if (fibcount <= 1){
currentmod = fibcount % mod;
al.add (currentmod);
sum += fibcount;
}
else {
fib = getFib (FNum, SNum);
FNum = SNum;
SNum = fib;
currentmod = (fib % mod);
al.add (currentmod);
sum += fib;
}
if ((currentmod == 0 & (sum % mod) == 0) & fibcount > 0){
return fibcount;
}
fibcount++;
}
return mod; //essentially just to satisfy the return condition
}
}
*當需要計算的斐波那契數量變得非常大時,例如100 000,這個問題就出現了。* - 我認爲你對斐波那契數的感覺錯了。它們以指數級的速度快速增長 - 長的範圍超過了第93個斐波納契數。 – Leon
@Leon哦,那比我想象的要糟糕得多。儘管我知道他們成倍增長,但我不知道這麼快就會傳出。 – Airdish