
// FermatNumbers.java
// Andrew Davison, ad@coe.psu.ac.th, April 2023

/* A Fermat number is a positive integer of the form:
        2^(2^k) + 1

   The first few Fermat numbers:
      3, 5, 17, 257, 65537, 4294967297, 18446744073709551617

   https://en.wikipedia.org/wiki/Fermat_number
and
   https://www.geeksforgeeks.org/program-to-find-first-n-fermat-numbers/

   The code uses Nut's pow() and ArithmeticUtils's pow(), 
   and there's also versions in Java's Math, BigInteger, and 
   BigDecimal classes.

*/

import java.math.*;

import org.apache.commons.numbers.core.ArithmeticUtils;


public class FermatNumbers
{
  private static final int MAX = 8;

  private static BigInteger two = BigInteger.valueOf(2);


  public static void main(String[] args)
  {
    System.out.println("Fermat Numbers using long");
    for (long i = 0; i < MAX; i++) {
      int pow = (int)Math.pow(2, i);
      System.out.println(i + " (2^" + pow + ") = " + fermatLong(i));
    }

    System.out.println("\nFermat Numbers using BigInteger");
    for (long i = 0; i < MAX; i++) {
      int pow = (int)Math.pow(2, i);
      System.out.println(i + " (2^" + pow + ") = " + 
                              fermatBI(BigInteger.valueOf(i)));
    }
  } /* main */


  private static long fermatLong(long n)
  // Calculate 2^2^i
  { return Nut.pow(2L, 
                 Nut.pow(2L, n)) + 1L;  } 


  private static BigInteger fermatBI(BigInteger n)
  // Calculate 2^2^i
  { return ArithmeticUtils.pow(two, 
                  ArithmeticUtils.pow(two, n)).add(BigInteger.ONE);  } 


} // end of FermatNumbers class
