Monday, August 17, 2015

BigInteger - Storing Infinitely long numbers

Say you need to take an input number that is really huge. So huge that it won't fit into a long or even a double. Then how do you do it?

Method 1: ArrayList

Take in each digit in an array list and then compute the length of the array.

Now what if you need to add 2 such huge numbers? Or say you want to count the number of sets of numbers you can get from a given set of digits - 1234 can be {1,2,3,4} or {1,23,4} or {12,34} so on. And if you have infinite such digits, how can you store your count?

This is where Method 2 comes

Method 2: BigInteger & BigDecimal

From what I understand, BigInteger & BigDecimal classes can hold a number/ decimal or any length, as long as the JVM has heap memory available to store the number.

Here are useful functions of BigInteger that I learnt today:

1. Initializing using numbers zero, one and ten

BigInteger cnt = BigInteger.ZERO;
BigInteger cnt = BigInteger.ONE;
BigInteger cnt = BigInteger.TEN;

2. Initializing using Other numbers

BigInteger cnt = BigInteger.valueOf(15);

3. Operations such as mod, divide, add

BigInteger modTen = cnt.mod(BigInteger.TEN);
BigInteger modTen = cnt.mod(BigInteger.valueOf(10));
cnt  = cnt.add(BigInteger.valueOf(1));
BigInteger divTen = cnt.divide(BigInteger.TEN);

4. Comparisons between 2 BigIntegers

//a,b are BigIntegers
int output = a.compareTo(b);
a<b, then output = -1
a=b, then output = 0
a>b, then output = 1

5. Converting to primitive data types & displaying on console for debugging

BigInteger modTen = big.mod(BigInteger.TEN);
if(modTen.intValue() > 0) System.out.println(modTen);

Sample Code


//helper functions 
 private BigInteger bigInt(int smallVal)
 {
  return BigInteger.valueOf(smallVal);
 }

 private boolean valid(BigInteger big) {

  if(big.compareTo(bigInt(0)) == 1 && big.compareTo(bigInt(27)) == -1)
   return true;
  return false;
 }

 BigInteger perm(BigInteger big)
 {
  BigInteger cnt = BigInteger.ZERO;
  if(big.equals(BigInteger.ZERO)) return cnt;
  BigInteger modTen = big.mod(BigInteger.TEN);
  BigInteger divTen = big.divide(BigInteger.TEN);

  if(modTen.intValue() > 0 && divTen.equals(BigInteger.ZERO)  )
  {
   return valid(modTen)? BigInteger.ONE: BigInteger.ZERO; 
  }

  BigInteger mod100 = big.mod(bigInt(100));
  BigInteger div100 = big.divide(bigInt(100));

  if(mod100.intValue() > 0 && div100.equals(bigInt(0)))
  {
   if(valid(big)) cnt  = cnt.add(bigInt(1));
   if(valid(modTen) && valid(divTen)) cnt = cnt.add(bigInt(1));
      
   return cnt;
  }

  if(valid(modTen)) cnt = cnt.add(perm(divTen));
  if(valid(mod100)) cnt = cnt.add(perm(div100));
  return cnt;
 }

No comments:

Post a Comment