/*---- Assumes both HugeIntegers are positive and this > that -----------------*/
 public HugeInteger subtract(HugeInteger that) {
   if (this.compareTo(that) < 0) return that.subtract(this);
   HugeInteger result = new HugeInteger(this.size());
   int borrow = 0;
   int difference;
   int position = 0;
   for (; position < that.size(); position++) {
     difference = this.digitAt(position) - that.digitAt(position) - borrow;
     if (difference < 0) {
       difference += 10;
       borrow = 1;
     } else {
       borrow = 0;
     }
     result.addDigit(difference);
     DIGIT_OPERATIONS++;
   }
   for (; position < this.size(); position++) {
     difference = this.digitAt(position) - borrow;
     if (difference < 0) {
       difference += 10;
       borrow = 1;
     } else {
       borrow = 0;
     }
     result.addDigit(difference);
     DIGIT_OPERATIONS++;
   }
   result.removeLeadingZeroes();
   return result;
 }
 /*---- returns a copy of the digits of this from provided integer to size()-1 -*/
 public HugeInteger lowerCopy(int midPoint) {
   HugeInteger result = new HugeInteger(midPoint);
   for (int i = 0; i < midPoint; i++) {
     result.addDigit(this.digitAt(i));
   }
   // result.removeLeadingZeroes();
   return result;
 }
  /*---- returns the sum of this and the provided HugeInteger -------------------*/
  public HugeInteger add(HugeInteger that) {
    this.removeLeadingZeroes();
    that.removeLeadingZeroes();

    HugeInteger result = new HugeInteger(max(this.size(), that.size()));

    int carry = 0;
    int position = 0;
    int sum;
    while (position < min(this.size(), that.size())) {
      sum = this.digitAt(position) + that.digitAt(position) + carry;
      if (sum >= 10) {
        sum -= 10;
        carry = 1;
      } else {
        carry = 0;
      }
      result.addDigit(sum);
      position++;
      DIGIT_OPERATIONS++;
    }
    if (this.size() > that.size()) {
      while (position < this.size()) {
        result.addDigit(this.digitAt(position) + carry);
        carry = 0;
        position++;
        DIGIT_OPERATIONS++;
      }

    } else if (that.size() > this.size()) {
      while (position < that.size()) {
        result.addDigit(that.digitAt(position) + carry);
        carry = 0;
        position++;
        DIGIT_OPERATIONS++;
      }
    }
    if (carry == 1) {
      result.addDigit(1);
    }

    return result;
  }
 /*---- returns a copy of this shifted to the left by the specified amount -----*/
 public HugeInteger shift(int distance) {
   HugeInteger result = new HugeInteger(this.size() + distance);
   for (int i = 0; i < distance; i++) result.addDigit(0);
   for (int i = 0; i < this.size(); i++) result.addDigit(this.digitAt(i));
   return result;
 }