@Override
  public int compareTo(HugeInteger value) {
    HugeIntegerImpl other = (HugeIntegerImpl) value;

    if (this.sign != other.sign) return this.sign > other.sign ? 1 : -1;

    switch (this.sign) {
      case 1:
        return compareMagnitude(other.magnitude);
      case -1:
        return other.compareMagnitude(this.magnitude);
      default:
        return 0;
    }
  }
  @Override
  public HugeInteger subtract(HugeInteger value) {
    HugeIntegerImpl other = (HugeIntegerImpl) value;

    if (other.sign == 0) return this;
    if (this.sign == 0) return other.negate();

    if (this.sign != other.sign)
      return new HugeIntegerImpl(this.sign, add(this.magnitude, other.magnitude));

    int compare = compareMagnitude(other.magnitude);
    if (compare == 0) return ZERO;

    int resultSign = compare * this.sign;
    int[] resultMagnitude =
        (compare > 0)
            ? subtract(this.magnitude, other.magnitude)
            : subtract(other.magnitude, this.magnitude);

    return new HugeIntegerImpl(resultSign, resultMagnitude);
  }