## Homework J4## Due: Friday, 14 October 2005 by 10 a.m. |

In this homework, you will implement a few exercises on integers in order
to gain more experience using Java control structures, such as `for` loops,
`while` loops, and `if-else` statements. In the process you will deal
with some very large numbers, so you will also use the
BigInteger class that Java provides
to manipulate very large integers. The BigInteger class is in the
java.math library, so you will have to have the following line at the top of
your program:

`import java.math.*;`

Your code should be in a NumberGames class in a file named NumberGames.java.

This assignment is longer than the previous assignments. The best way to tackle it is to do one part at a time, and test that part. Once it works, move on to the next part.

An `int` can only represent a certain range of numbers, approximately -2 billion to +2 billion.
The Java primitive variable type` long `can represent a larger, but still finite, range.
Java's
BigInteger class supports integers of unlimited size, though arithmetic operations on
BigIntegers can be significantly slower than on `int` and `long`. For this assignment
you will use the BigInteger class to store the very large numbers which
can result from the Fibonacci, primality, and exponentiation computations described above.
In particular, we are going to be testing your code with values that are larger
than a` long `can hold, so you will have to use BigInteger.

For example, the following code creates two BigIntegers, and adds them together to create a third BigInteger.

`BigInteger bignum1 = new BigInteger ("234238947239487");
BigInteger bignum2 = new BigInteger ("12349871239487123984");
BigInteger bignum3 = bignum1.add(bignum2);`

Note that unlike a StringBuffer, each BigInteger method call creates a *new*
BigInteger -- it does not modify the existing one.

In this assignment you have the user input a number (let's call it
*i*), then calculate and print the *i*^{th} Fibonacci number,
the number 2^{i}, all all the prime numbers less than *i*. Note that if you enter
a very large value of *i* (say, 100), then your program will take a **very** long
time (especially the prime number part). Thus, experiment with smaller
values of *i* until you know your program is working.

The *i*^{th} Fibonacci number is defined as the sum of the
previous two Fibonacci numbers. The first and second Fibonnaci numbers are always defined as 1 and 1. In other words, each Fibonacci number is equal to the sum of the two
before it in the sequence, with the first two numbers starting the sequence at 1. Thus the
first few terms of the Fibonacci sequence are:

1 1 2 3 5 8 13 21 34 55 ...

because 1+1=2, 1+2=3, 2+3=5, 3+5=8, and so on. Let *f*(*n*)
be the *n*^{th} Fibonacci number. Thus, *f*(1) is 1, *
f*(2) is 1, *f*(3) is 2, *f*(10) is 55, etc. The formal
definition for the Fibonacci sequence is:

f(1) = 1

f(2) = 1

f(n) =f(n-1) +f(n-2) whenn> 2

This will require a` while `or` for `loop, where each iteration of
the loop computes the next term of the sequence. Because the Fibonacci numbers get large very quickly, you will
have to use the BigInteger class to hold the numbers. Once your program
has computed *i*^{th} Fibonacci number, it
should be printed out to the screen.

You are welcome to print out all the Fibonacci numbers as they are computed. However, at the end of that, you need to print out something along the lines of, "the 10th Fibonacci number is 55".

For this part of the assignment, you will use the same value for *i*, and compute the *exact *
integer value of 2* ^{i}*. Java provides routines for exponentiation, but they are based on
floating point arithmetic and logarithms; if

You are welcome to print out all the powers of 2 as they are
computed. However, at the end of that, you need to print out something
along the lines of, "the 10th power of 2 is 1024". You may **
not** use the` pow() `method in the BigInteger class.

Note that 1 is not a prime number! (really) Thus, the first prime number is 2.

For this part of this assignment, you will use the same number *i* already
input by the user, and print out all the prime numbers less than or equal to *i*. Note that this is
different from printing out the *i*^{th} prime number. For
example, if the user enters 6, you should print out all the prime numbers less
than or equal to 6 (2, 3, 5), and not the 6th prime number (13, as the prime
numbers go 2, 3, 5, 7, 11, 13).

Because prime numbers do not increase very rapidly (compared with the other
parts), you should use` int `variables for this part. You will notice that BigInteger class (described
above) provides some methods for finding primes: `isProbablePrime()`, `nextProbablePrime()`, and `probablePrime()`.
Needless to say, you are **not** allowed to use these methods, or any code based on these methods.

To test whether a number *n* is prime, you will need to use nested`
for `or` while `loops.
For each number *n* that you are testing for primality (those numbers range
from 2 to *i*), you need to test all numbers (we'll call them *j*) from 2 to *
n*-1 to see if
any of them divide *n* evenly (remember the modulus operator: `%`).
The loop for the numbers *n* form the outer nested loop, and the loop for
the numbers *j* forms the inner nested loop. In the process you may wish to use a` boolean
`variable to indicate whether the computation has
yet found a value of *j* which evenly divides *n*. For example, such a variable might
called "`foundFactor`" and initialized to` false `at the beginning of each primality test.
A` boolean `variable used this way is often called a *flag*.

This last part deals with measuring the speed of the computations of the
above parts. The System class provides a method to get the current time: `System.currentTimeMillis()`.
This method returns a` long`, which is the total number of milliseconds
since January 1, 1970.
Thus, the numbers returned by it are going to be rather large. You can get the current
time (number of milliseconds) by the following code:

`long currentTime = System.currentTimeMillis();`

You need to store the current time before each of the three parts described
above, and then once the computation is done, determine (based on the initial
time that was stored and the current time through another call to `System.currentTimeMillis()`)
how long the computation took. The total number of milliseconds taken for
each of the three parts described above should be printed out to the
screen.

The good programming practices from HW J1 need to be in this homework as well.

We are not providing a sample execution for this program. However, in order to test your program, you may wish to know the following:

- The first 20 Fibonacci numbers:

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 - The first 20 prime numbers (remember that 1 is not prime):

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 - The first 20 powers of two:

2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576

You may assume that we will not test it with any value of *i* less than
5. This may make your code simpler, since you will not have to handle special
cases such as *i*=1 and *i*=2.

This program will require loops, including nested loops. For some computations a` while
`loop will probably feel more natural, while for others a` for `loop will probably be
more straightforward to code. You can use whatever you prefer.
Remember to consider all the loop constructs that Java provides when coding this
assignment.

Although we will not provide a sample execution, we will provide what the values should be.

For *i*=10

- The 10
^{th}Fibonacci number is 55 - 2
^{10}= 1024 - The prime numbers less than 10 are: 2, 3, 5, 7

For *i*=50

- The 50
^{th}Fibonacci number is 12586269025 - 2
^{50}= 1125899906842624 - The prime numbers less than 50 are: 2, 3, 5, 7 11 13 17 19 23 29 31 37 41 43 47

For *i*=100 (this may take a *very* long time)

- The 100
^{th}Fibonacci number is 354224848179261915075 - 2
^{100}= 1267650600228229401496703205376 - The prime numbers less than 100 are: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

When you are finished, submit the NumberGames.java file.