L7: the max-dimension of results is digits.length + n.digits.length.<>public class LongInteger extends SignedNumeral<LongInteger> {
/** The values of this integer (excluding the sign). */
protected byte[] digits;
.../** Creates a long integer with the default value of "0". */
public LongInteger() {
this("0");
}
/**
* Creates a long integer by copying the specific object.
* @param n the object to be copied.
*/
public LongInteger(LongInteger n) {
super(n.sign);
digits = Arrays.copyOf(n.digits, n.digits.length);
}
/**
* Creates a long integer with the specific sign and values.
* @param n the sign and values to be set.
* @see #set(String)
*/
public LongInteger(String n) {
set(n);
}/**
* Sets the sign and values of this integer.
* @param n the sign and values to be set.
* @throws NullPointerException when `n` is null.
* @throws InvalidParameterException when `n` contains non-digit character
* except for the first character that can be [+-\d].
*/
public void set(String n) {
// 'n' must not be null
if (n == null)
throw new NullPointerException();
// set this.sign
sign = switch (n.charAt(0)) {
case '-' -> { n = n.substring(1); yield Sign.NEGATIVE; }
case '+' -> { n = n.substring(1); yield Sign.POSITIVE; }
default -> Sign.POSITIVE;
};
// set this.digits
digits = new byte[n.length()];
for (int i = 0, j = n.length() - 1; i < n.length(); i++, j--) {
byte v = (byte)(n.charAt(i) - 48);
if (0 > v || v > 9) {
String s = String.format("%d is not a valid value", v);
throw new InvalidParameterException(s);
}
digits[j] = v;
}
}@Override
public void add(LongInteger n) {
if (sign == n.sign)
addSameSign(n);
else
addDifferentSign(n);
}/**
* Adds the specific integer that has the same sign as this integer.
* @param n the integer to be added with the same sign.
*/
protected void addSameSign(LongInteger n) {
// copy this integer to result[]
int m = Math.max(digits.length, n.digits.length);
byte[] result = new byte[m + 1];
System.arraycopy(digits, 0, result, 0, digits.length);
// add n to result
for (int i = 0; i < n.digits.length; i++) {
if (i < n.digits.length)
result[i] += n.digits[i];
if (result[i] >= 10) {
result[i] -= 10;
result[i + 1] += 1;
}
}
// set this.digits
digits = result[m] == 0 ? Arrays.copyOf(result, m) : result;
}/**
* Adds the specific integer that has a different sign from this integer.
* @param n the integer to be added with a different sign
*/
protected void addDifferentSign(LongInteger n) {
throw new UnsupportedOperationException();
}@Override
public void multiply(LongInteger n) {
// set this.sign
sign = (sign == n.sign) ? Sign.POSITIVE : Sign.NEGATIVE;
// multiply this and n and save it to result
byte[] result = new byte[digits.length + n.digits.length];
for (int i = 0; i < digits.length; i++) {
for (int j = 0; j < n.digits.length; j++) {
int k = i + j, prod = digits[i] * n.digits[j];
result[k] += prod;
result[k + 1] += result[k] / 10;
result[k] %= 10;
}
}
// set this.digits
int m; for (m = result.length - 1; m > 0; m--)
if (result[m] != 0) break;
digits = ++m < result.length ? Arrays.copyOf(result, m) : result;
}public class LongIntegerRun {
static public void main(String[] args) {
System.out.println(args);
}
}[Ljava.lang.String;@d716361static public void main(String[] args) {
System.out.println(Arrays.toString(args));
}[][123, -456]static public void main(String[] args) {
LongInteger a = new LongInteger(args[0]);
LongInteger b = new LongInteger(args[1]);
System.out.println(a);
System.out.println(b);
}edu.emory.cs.algebraic.LongInteger@4d7e1886
edu.emory.cs.algebraic.LongInteger@3cd1a2f1public class LongInteger extends SignedNumeral<LongInteger> {
...
@Override
public String toString() {
StringBuilder build = new StringBuilder();
if (sign == Sign.NEGATIVE) build.append("-");
for (int i = digits.length - 1; i >= 0; i--)
build.append(digits[i]);
return build.toString();
}
...String s = "";
if (sign == Sign.NEGATIVE) s += "-";
for (int i = digits.length - 1; i >= 0; i--)
s += digits[i];
return s;123
-456boolean c = a < b; // gives a compile errorpublic class LongInteger extends SignedNumeral<LongInteger>
implements Comparable<LongInteger> {
...
}@Override
public int compareTo(LongInteger n) {
if (isPositive())
return n.isNegative() ? 1 : compareAbs(n);
else
return n.isPositive() ? -1 : -compareAbs(n);
}/**
* @param n the object to be compared.
* @return a negative integer, zero, or a positive integer as the absolute value of this object is
* less than, equal to, or greater than the absolute value of the specified object.
*/
public int compareAbs(LongInteger n) {
int diff = digits.length - n.digits.length;
if (diff == 0) {
for (int i = digits.length - 1; i >= 0; i--) {
diff = digits[i] - n.digits[i];
if (diff != 0) break;
}
}
return diff;
}static public void main(String[] args) {
List<LongInteger> list = new ArrayList<>();
list.add(new LongInteger("78"));
list.add(new LongInteger("-45"));
list.add(new LongInteger("0"));
list.add(new LongInteger("6"));
list.add(new LongInteger("-0"));
list.add(new LongInteger("-123"));
list.sort(Comparator.naturalOrder());
System.out.println(list);
list.sort(Comparator.reverseOrder());
System.out.println(list);
}[-123, -45, -0, 0, 6, 78]
[78, 6, 0, -0, -45, -123]package edu.emory.cs.algebraic;
public class Numeral {
}public class Numeral {
/**
* Adds `n` to this numeral.
* @param n the numeral to be added.
*/
public void add(Numeral n) { /* cannot be implemented */ }
}public interface Numeral {
void add(Numeral n);
}public interface SignedNumeral extends Numeral {
/** Flips the sign of this numeral. */
void flipSign();
/**
* Subtracts `n` from this numeral.
* @param n the numeral to be subtracted.
*/
default void subtract(Numeral n) {
n.flipSign();
add(n);
n.flipSign();
}
}default void subtract(Numeral n) {
((SignedNumeral)n).flipSign();
add(n);
((SignedNumeral)n).flipSign();
}default void subtract(SignedNumeral n) {
n.flipSign();
add(n);
n.flipSign();
}public interface SignedNumeral extends Numeral {
@Override
void add(SignedNumeral n);
...public interface SignedNumeral extends Numeral {
void add(SignedNumeral n);
...public interface Numeral<T extends Numeral<T>> {
void add(T n);
}public interface SignedNumeral extends Numeral<SignedNumeral> {
void flipSign();
default void subtract(SignedNumeral n) {
n.flipSign();
add(n);
n.flipSign();
}
}void add(SignedNumeral n);public class LongInteger implements SignedNumeral {
@Override
public void flipSign() { /* to be implemented */ }
@Override
public void add(SignedNumeral n) { /* to be implemented */ }
}public interface SignedNumeral<T extends SignedNumeral<T>> extends Numeral<T> {
void flipSign();
default void subtract(T n) {
n.flipSign();
add(n);
n.flipSign();
}
}public enum Sign {
POSITIVE,
NEGATIVE;
}public enum Sign {
POSITIVE('+'),
NEGATIVE('-');
private final char value;
Sign(char value) {
this.value = value;
}
/** @return the value of the corresponding item. */
public char value() {
return value;
}
}public interface SignedNumeral<T extends SignedNumeral<T>> extends Numeral<T> {
Sign sign = Sign.POSITIVE;
.../** Flips the sign of this numeral. */
default void flipSign() {
sign = (sign == Sign.POSITIVE) ? Sign.NEGATIVE : Sign.POSITIVE;
}public abstract class SignedNumeral<T extends SignedNumeral<T>> implements Numeral<T> {
/** The sign of this numeral. */
protected Sign sign;
/**
* Create a signed numeral.
* the default sign is {@link Sign#POSITIVE}.
*/
public SignedNumeral() {
this(Sign.POSITIVE);
}
/**
* Create a signed numeral.
* @param sign the sign of this numeral.
*/
public SignedNumeral(Sign sign) {
this.sign = sign;
}
... ...
/** @return true if this numeral is positive; otherwise, false. */
public boolean isPositive() {
return sign == Sign.POSITIVE;
}
/** @return true if this numeral is negative; otherwise, false. */
public boolean isNegative() {
return sign == Sign.NEGATIVE;
}
/** Flips the sign of this numeral. */
public void flipSign() {
sign = isPositive() ? Sign.NEGATIVE : Sign.POSITIVE;
}
/**
* Subtracts `n` from this numeral.
* @param n the numeral to be subtracted.
*/
public void subtract(T n) {
n.flipSign(); add(n); n.flipSign();
}
/**
* Multiplies `n` to this numeral.
* @param n the numeral to be multiplied.
*/
public abstract void multiply(T n);
}import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class LongIntegerTest {
@Test
public void testConstructors() {
// default constructor
assertEquals("0", new LongInteger().toString());
// constructor with a string parameter
assertEquals("12", new LongInteger("12").toString());
assertEquals("34", new LongInteger("+34").toString());
assertEquals("-56", new LongInteger("-56").toString());
assertEquals("-0", new LongInteger("-0").toString());
// copy constructor
assertEquals("12", new LongInteger(new LongInteger("12")).toString());
assertEquals("-34", new LongInteger(new LongInteger("-34")).toString());
}
}Tests passed: 1 of 1 test@Test
public void testMultiply() {
LongInteger a = new LongInteger("123456789");
a.multiply(new LongInteger("1"));
assertEquals("123456789", a.toString());
a.multiply(new LongInteger("-1"));
assertEquals("-123456789", a.toString());
a.multiply(new LongInteger("-1234567890123456789"));
assertEquals("152415787517146788750190521", a.toString());
a.multiply(new LongInteger("0"));
assertEquals("0", a.toString());
a.multiply(new LongInteger("-0"));
assertEquals("-0", a.toString());
}@Test
public void testCompareTo() {
assertTrue(0 < new LongInteger("0").compareTo(new LongInteger("-0")));
assertTrue(0 > new LongInteger("-0").compareTo(new LongInteger("0")));
assertTrue(0 < new LongInteger("12").compareTo(new LongInteger("-34")));
assertTrue(0 > new LongInteger("-12").compareTo(new LongInteger("34")));
assertTrue(0 > new LongInteger("-34").compareTo(new LongInteger("12")));
assertTrue(0 < new LongInteger("34").compareTo(new LongInteger("-12")));
}