Fibonacci sequence for n > 46 Java

后端 未结 4 1942
旧时难觅i
旧时难觅i 2021-01-23 22:38

I have the following code which provides the correct values for n < 47.

public static int fib(int n) {
    int nthTerm = 0;
    if (n == 2)
        nthTerm =          


        
相关标签:
4条回答
  • 2021-01-23 23:16

    You can use this for transformated code into BigInteger.

    package your.pack
    
    import java.math.BigDecimal;
    import java.math.BigInteger;
    
    /**
     * Created on 3/6/16.
     */
    public class Fibonacci {
    
        private static BigDecimal goldenRatio = new BigDecimal((1 + Math.sqrt(5)) / 2);
        private static BigDecimal goldenRatioMin1 = goldenRatio.subtract(BigDecimal.ONE);
        private static BigDecimal sqrt5 = new BigDecimal(Math.sqrt(5));
    
        private static BigInteger fib(int n) {
            BigInteger nthTerm = new BigInteger("0");
            if (n == 2)
                nthTerm = BigInteger.ONE;
            else {
                BigDecimal minResult = goldenRatio.pow(n).subtract(goldenRatioMin1.pow(n));
                nthTerm = minResult.divide(sqrt5,0).toBigInteger();
    
                if (n % 2 == 1 && n < 45){
                    nthTerm = nthTerm.add(BigInteger.ONE);
                }
    
            }
            return nthTerm;
        }
    
        private static int fib2(int n) {
            int nthTerm = 0;
            if (n == 2)
                nthTerm = 1;
            else {
                double goldenRatio = (1 + Math.sqrt(5)) / 2;
                nthTerm = (int) (Math.round(Math.pow(goldenRatio, n)
                        - Math.pow(1 - goldenRatio, n)) / Math.sqrt(5));
    
                if (n % 2 == 1 && n < 45)
                    nthTerm++;
            }
            return nthTerm;
        }
    
        public static void main(String []args){
            System.out.println(
                    fib(47)
            );
        }
    
    }
    

    Method fib2 is your code, fib is the transformed into BigInteger. Cheers

    0 讨论(0)
  • 2021-01-23 23:23

    If you use long, you support perfectly the range over 1000; but if you want support all possible value then you need use BigInteger.

    A example use long:

    public static long fib(int n) 
    {
        long f0 = 1;
        long f1 = 1;
    
        long c = 2;
    
        while(c < n)
        {
            long tmp = f0+f1;
            f0 = f1;
            f1 = tmp;
            c++;
        }
    
        return f1;
    }
    
    0 讨论(0)
  • 2021-01-23 23:24

    Use long instead of using int, and remember to cast the value from Math.round() to long as well (by writing (long) Math.round(...) just as you casted to int) .

    0 讨论(0)
  • 2021-01-23 23:25

    The reason you can't use int is because fib(47) is 2971215073 which overflows Java's signed 32-bit int (231-1). You could use a memoization optimization to implement it with BigInteger like,

    private static Map<Integer, BigInteger> memo = new HashMap<>();
    static {
        memo.put(0, BigInteger.ZERO);
        memo.put(1, BigInteger.ONE);
    }
    
    public static BigInteger fib(int n) {
        if (memo.containsKey(n)) {
            return memo.get(n);
        }
        BigInteger v = fib(n - 2).add(fib(n - 1));
        memo.put(n, v);
        return v;
    }
    
    0 讨论(0)
提交回复
热议问题