1

I am trying to create a program which will generate numbers in the Fibonacci sequence until it finds a 1,000 digit number which is in the sequence. The code I have used runs fine and give a valid output, however, I have had trouble retrieving the length of each number; using BigInteger I have converted the BigInteger to a String and used the String.length() method to get the length, however, I have found that this is not giving the real length, and I can not see why.

import java.util.ArrayList;
import java.math.BigInteger;
public class problemTwentyFive {
  public static void main(String [] args) {
     ArrayList<BigInteger> fibonacciNumbers = new ArrayList<BigInteger>();
     boolean validNo = true;
     int x = 2;
     BigInteger tempAns = new BigInteger(""+0);
     fibonacciNumbers.add(new BigInteger(""+x));
     fibonacciNumbers.add(new BigInteger(""+x));
     do {
      tempAns = fibonacciNumbers.get(x-1).add(fibonacciNumbers.get(x-2));
      if (tempAns.toString().length() <= 1000) {
         System.out.println(tempAns.toString().length());
         if(tempAns.toString().length() == 1000) {
            fibonacciNumbers.add(tempAns);
            validNo = false;
            break;
        } else {
           fibonacciNumbers.add(tempAns);
        }
      }
      x++;
      if (tempAns.toString().length() > 1000) {
         validNo = false;
         break;
      }
      System.out.println(tempAns);
   } while (validNo == true);
   System.out.println("The first term in the Fibonacci sequence to contain 1,000 digits is term: " + fibonacciNumbers.size());
  }
}

Is there a better way to get the length of a BigInteger? I have alread reffered to the question thBigInteger: count the number of decimal digits in a scalable method

Update Text text which is outputted after running the program is:

The first term in the Fibonacci sequence to contain 1,000 digits is term: 4781

We know this is false because if we look at the project I am attempting, when we input 4781 as the answer, it is incorrect. Click here to view the project (Project Euler - Problem 25)

Community
  • 1
  • 1
  • 1
    What do you mean by "is not giving the real length"? What are you expecting, and what is it giving? Please provide a short but complete example demonstrating the problem - which probably *doesn't* need to use the Fibonacci sequence. – Jon Skeet Feb 19 '15 at 11:53
  • 1
    Please show an example of a (non-negative) BigInteger whose length is not correctly found using `toString().length()` – DNA Feb 19 '15 at 11:53
  • @JonSkeet I've updated what output is given, I can't provide the actual number as 1,000 digits is a lot to add to a post like this. –  Feb 19 '15 at 12:01
  • 1
    Also look at `bitLength() * Math.log10(2)`. – Catalina Island Feb 19 '15 at 12:02
  • @DNA I've updated the final output given from the program. –  Feb 19 '15 at 12:02
  • 4
    Note how the answer you've accepted indicates that the problem *isn't* finding the length. That's why I've suggested you should try to separate out "how can I find the length" from "why isn't my program working" - you made an assumption that it was because of the length checking, but that turned out not to be the case. – Jon Skeet Feb 19 '15 at 12:42

4 Answers4

2

When this code is executed (i.e. the solution is found):

            if ((tempAns.toString().length()) == 1000)
            {
                fibonacciNumbers.add(tempAns);
                validNo = false;
                break;
            }

The tempAns is not printed. That's why your last printed number is only 999 digits long.

If you add a System.out.println("and is: " + tempAns); at the end, just before the end of the main method you will get the desired number. And the answer is thus 4781 + 1 = 4782

Burkhard
  • 14,596
  • 22
  • 87
  • 108
1

I think the real problem is that you are starting your series with the values 2,2,... but it should be 1,1,...

Here:

 int x = 2;
 BigInteger tempAns = new BigInteger(""+0);
 fibonacciNumbers.add(new BigInteger(""+x));
 fibonacciNumbers.add(new BigInteger(""+x));

Should be:

 int x = 2;
 BigInteger tempAns = new BigInteger(""+0);
 fibonacciNumbers.add(new BigInteger(""+1));
 fibonacciNumbers.add(new BigInteger(""+1));

That makes your series reach the 1000 length value one term later giving you the real answer Bukhard gave you (for the wrong reasons I think, because you ARE adding the value with length 1000).

JGilardi
  • 46
  • 4
  • @James : @JGilardi is right : the posted code does not give a Fibo serie : (2, 2, 4, 6, ...). You should initialise with one's : (1, 1, 2, 3, 5, 8...). The variable `x` tracks only the index of the current fibo number in the sequence. But OTOH, this is not the cause of your problem of length. – T.Gounelle Feb 19 '15 at 14:18
  • @Abbé Résina: If we count for example the length of the series until we reach the first number with to digits (to make it shorter) you get different lengths. (1,1,2,3,5,8,13) has lenght 7 while (2,2,4,6,10) has lenght 5. – JGilardi Feb 19 '15 at 14:58
  • you are right, there was actually 2 pbs in this code – T.Gounelle Feb 19 '15 at 16:23
1

This looks way simpler to me:

import java.math.BigInteger;

public class Problem25_1000erFib {

    public static void main(String[] args) {

        BigInteger fib1 = new BigInteger("1");
        BigInteger fib2 = new BigInteger("1");
        BigInteger fib3 = new BigInteger("2");
        int count = 3;

        do {
            count++;
            fib1 = fib2;
            fib2 = fib3;
            fib3 = fib1.add(fib2);
        } while (fib3.toString().length() < 1_000);

        System.out.println(count);
    }
}
Philipp
  • 11
  • 2
0

The code looks more complex than it should with duplications of code and many branches. For instance, you test (... <= 1000) and (... = 1000) and then again (... > 1000). The logic is not easy to follow. I kept your algorithm but just remove the noise of all these branching tests :

public static void main(String [] args) {
        ArrayList<BigInteger> fibonacciNumbers = new ArrayList<BigInteger>();
        boolean validNo = true;
        int x = 2;
        BigInteger tempAns = null;
        fibonacciNumbers.add(BigInteger.valueOf(1));
        fibonacciNumbers.add(BigInteger.valueOf(1));
        do {
            tempAns = fibonacciNumbers.get(x-1).add(fibonacciNumbers.get(x-2));
            fibonacciNumbers.add(tempAns);
            x++;
            System.out.println("x=" + x + ", length=" + tempAns.toString().length());
            if(tempAns.toString().length() >= 1000) {
                validNo = false;
            }
        } while (validNo == true);
        System.out.println("The first term in the Fibonacci sequence to contain 1,000 digits is term: " + fibonacciNumbers.size());
    }
T.Gounelle
  • 5,953
  • 1
  • 22
  • 32