Java BigInteger implementation The Next CEO of Stack Overflow

Are there any limitations on attacking while grappling?

How fast would a person need to move to trick the eye?

Is it possible to search for a directory/file combination?

What happens if you roll doubles 3 times then land on "Go to jail?"

Solving Integral Equation by Converting to Differential Equations

How do scammers retract money, while you can’t?

MessageLevel in QGIS3

"and that skill is always a class skill for you" - does "always" have any meaning in Pathfinder?

Can I equip Skullclamp on a creature I am sacrificing?

Would a galaxy be visible from outside, but nearby?

How to add tiny 0.5A 120V load to very remote split phase 240v 3 wire well house

Why has the US not been more assertive in confronting Russia in recent years?

What does convergence in distribution "in the Gromov–Hausdorff" sense mean?

Is there an analogue of projective spaces for proper schemes?

What benefits would be gained by using human laborers instead of drones in deep sea mining?

Written every which way

What connection does MS Office have to Netscape Navigator?

If a black hole is created from light, can this black hole then move at speed of light?

SQL Server 2016 - excessive memory grant warning on poor performing query

What is ( CFMCC ) on ILS approach chart?

Why do professional authors make "consistency" mistakes? And how to avoid them?

If the heap is initialized for security, then why is the stack uninitialized?

Indicator light circuit

Why do we use the plural of movies in this phrase "We went to the movies last night."?



Java BigInteger implementation



The Next CEO of Stack Overflow










0












$begingroup$


I've written a java application that can handle operations on big integers implemented with array list of digits.



I have a difficulity with the way I implemented the divide method, because when the difference between the two numbers is high, the operation can take a huge amount of time.



I'd like to hear your thoughts about this implementation and ways it can be improved. Here is the class and it's test class:



BigInt.java



import java.util.ArrayList;

public class BigInt implements Comparable<BigInt>

private static final char MINUS_CHAR = '-';
private static final char PLUS_CHAR = '+';

// Saves the digits of the number - last element represents the smallest unit of the number
private ArrayList<Integer> numberDigits = new ArrayList<>();

// Indication if the number is negative
private boolean negative;

// String representation as given by the user
private String stringNumber;

BigInt(String number)

if (number.equals(""))
stringNumber = "0";
numberDigits.add(0);

else
// Dealing with the positive/negative signs
char firstChar = number.charAt(0);
if (firstChar == MINUS_CHAR


private boolean isNegative()
return negative;


private void flipNegativity()
if (stringNumber == "0")
return;

negative = !negative;
if (stringNumber.charAt(0) == MINUS_CHAR)
stringNumber = stringNumber.substring(1);
else
stringNumber = MINUS_CHAR + stringNumber;



// Adding another bigInt number to the current bigInt number
BigInt plus(BigInt otherNumber)

// current is negative, other is positive - subtract current from the other
if (negative && !otherNumber.isNegative())
return otherNumber.minus(new BigInt(stringNumber));


// other is negative - subtract its value
if (otherNumber.isNegative())
return minus(new BigInt(otherNumber.toString()));


// Setting the longer number of the two numbers
ArrayList<Integer> longerNumber, shorterNumber;
if (numberDigits.size() >= otherNumber.numberDigits.size())
longerNumber = numberDigits;
shorterNumber = otherNumber.numberDigits;

else
longerNumber = otherNumber.numberDigits;
shorterNumber = numberDigits;


int lengthsDifferences = longerNumber.size() - shorterNumber.size();


StringBuilder resultString = new StringBuilder();

// Initializing a carry for every addition
int carry = 0;


// Iterating from smallest unit digit to the biggest
for (int index = shorterNumber.size() - 1; index >= 0; index--)
int shorterNumberDigit = shorterNumber.get(index);
int longerNumberDigit = longerNumber.get(index + lengthsDifferences);

int newDigit = shorterNumberDigit + longerNumberDigit + carry;

// Calculating the carry and the new digit
carry = newDigit / 10;
newDigit = newDigit % 10;

resultString.append(newDigit);


// Adding digits of longer number
for (int index = lengthsDifferences - 1; index >= 0; index--)
int currDig = longerNumber.get(index);

// Check if need to add carry
if (currDig + carry == 10)
resultString.append(0);
carry = 1;
else
resultString.append(currDig + carry);
carry = 0;



// Check if there is carry on last digit
if (carry > 0)
resultString.append(carry);

return new BigInt(resultString.reverse().toString());


BigInt minus(BigInt otherNumber)

// If the other number is negative, add its value
if (otherNumber.isNegative())
return plus(new BigInt(otherNumber.stringNumber));


// subtract a bigger number than the current
if (this.compareTo(otherNumber) < 0)
BigInt result = otherNumber.minus(this);
result.flipNegativity();
return result;


// Other number is positive and not greater than current:
int lengthsDifferences = numberDigits.size() - otherNumber.numberDigits.size();

StringBuilder resultString = new StringBuilder();

int carry = 0;

for (int index = otherNumber.numberDigits.size() - 1; index >=0 ; index--)
int biggerNumDig = numberDigits.get(index + lengthsDifferences) - carry;
int smallerNumDig = otherNumber.numberDigits.get(index);

carry = 0;

if (biggerNumDig < smallerNumDig)
carry = 1;
biggerNumDig += 10;


resultString.append(biggerNumDig - smallerNumDig);


for (int index = lengthsDifferences - 1; index >=0 ; index--)
int currDig = numberDigits.get(index);

// Check if carry is needed
if (carry > currDig)
resultString.append(currDig + 10 - carry);
carry = 1;
else
resultString.append(currDig - carry);
carry = 0;



return new BigInt(resultString.reverse().toString());


// Multiply bigInt
BigInt multiply(BigInt otherNumber) isNegative() && !otherNumber.isNegative())
finalResult.flipNegativity();

return finalResult;


BigInt divide(BigInt otherNumber)

if (isBigIntZero(otherNumber))
throw new ArithmeticException();

// Handling the case where the current number is positive and the other is negative
if (otherNumber.isNegative() && !isNegative())
BigInt result = divide(new BigInt(otherNumber.stringNumber));
result.flipNegativity();
return result;

// Handling the case where the current number is negative and the other is positive
else if (!otherNumber.isNegative() && isNegative())
BigInt result = new BigInt(stringNumber).divide(otherNumber);
result.flipNegativity();
return result;


int compareResult = this.compareTo(otherNumber);
if (compareResult == 0)
return new BigInt("1");
else if (compareResult < 0)
return new BigInt("0");

BigInt result = new BigInt("0");
BigInt tempNumber = new BigInt("0");

while (tempNumber.compareTo(this) < 0)
tempNumber = tempNumber.plus(otherNumber);
result = result.plus(new BigInt("1"));


return result;



private boolean isBigIntZero(BigInt number)
return number.stringNumber.replace("0", "").equals("");



// Multiply a unit of BigInt with an integer. Example: 1000000000000000000 * 54
private BigInt MultiplyUnit(int majorUnits)

// Setting the string representation
String majorUnitsString = String.valueOf(majorUnits);
String newNumber = majorUnitsString + stringNumber.substring(1);

return new BigInt(newNumber);


private void multiplyByTen()
this.numberDigits.add(0);
stringNumber += '0';


@Override
public int compareTo(BigInt other)

// Current is negative, other is positive
if (isNegative() && !other.isNegative())
return -1;

// Current is positive, other is negative
else if (!isNegative() && other.isNegative())
return 1;


// Both are negative
else if (isNegative())
// Current is negative and has more digits - therefore it is smaller
if (numberDigits.size() > other.numberDigits.size())
return -1;
// Current is negative and has less digits - Therefore it is bigger
else if (numberDigits.size() < other.numberDigits.size())
return 1;

// Both have same number of digits - need to iterate them
else
for (int index = 0; index < numberDigits.size(); index++)

// Current has bigger negative digit - therefore it is smaller
if (numberDigits.get(index) > other.numberDigits.get(index))
return -1;

// Current has smaller negative digit - therefore it is smaller
else if (numberDigits.get(index) < other.numberDigits.get(index))
return 1;


// If we have reached here, the numbers are completely identical
return 0;


// If we have reached here, both numbers are positive

// Current is positive and has more digits - Therefore it is bigger
if (numberDigits.size() > other.numberDigits.size())
return 1;


// Current is positive and has less digits - Therefore it is smaller
else if (numberDigits.size() < other.numberDigits.size())
return -1;

// Both have same number of digits - need to iterate them
else
for (int index = 0; index < numberDigits.size(); index++)

// Current has bigger positive digit - therefore it is bigger
if (numberDigits.get(index) > other.numberDigits.get(index))
return 1;

// Current has smaller positive digit - therefore it is smaller
else if (numberDigits.get(index) < other.numberDigits.get(index))
return -1;


// If we have reached here, the numbers are completely identical
return 0;


@Override
public boolean equals(Object o)
// self check
if (this == o)
return true;

// null check
if (o == null)
return false;

// type check and cast
if (getClass() != o.getClass())
return false;

BigInt other = (BigInt) o;
// field comparison

return other.toString().equals(stringNumber);


@Override
public String toString()
return stringNumber;




Main



import com.sun.javaws.exceptions.InvalidArgumentException;

import java.util.Scanner;

public class Main

private static Scanner scanner = new Scanner(System.in);

public static void main(String[] args)
BigInt firstNumber;
BigInt secondNumber;

System.out.println("Enter first number: ");
firstNumber = inputBigIntNumber();

System.out.println("Enter second number: ");
secondNumber = inputBigIntNumber();

System.out.println("The result of plus is: " + firstNumber.plus(secondNumber));
System.out.println("The result of minus is: " + firstNumber.minus(secondNumber));
System.out.println("The result of multiply is: " + firstNumber.multiply(secondNumber));

try
System.out.println("The result of divide is: " + firstNumber.divide(secondNumber));
catch (ArithmeticException ex)
System.out.println("Can not divide by zero");




// Taking a valid integer input from the user (greater than 0)
private static BigInt inputBigIntNumber()

String str = scanner.nextLine();

while (true)
try
return new BigInt(str);

catch (IllegalArgumentException ex)
System.out.println("Invalid number, please try again: ");












share









$endgroup$
















    0












    $begingroup$


    I've written a java application that can handle operations on big integers implemented with array list of digits.



    I have a difficulity with the way I implemented the divide method, because when the difference between the two numbers is high, the operation can take a huge amount of time.



    I'd like to hear your thoughts about this implementation and ways it can be improved. Here is the class and it's test class:



    BigInt.java



    import java.util.ArrayList;

    public class BigInt implements Comparable<BigInt>

    private static final char MINUS_CHAR = '-';
    private static final char PLUS_CHAR = '+';

    // Saves the digits of the number - last element represents the smallest unit of the number
    private ArrayList<Integer> numberDigits = new ArrayList<>();

    // Indication if the number is negative
    private boolean negative;

    // String representation as given by the user
    private String stringNumber;

    BigInt(String number)

    if (number.equals(""))
    stringNumber = "0";
    numberDigits.add(0);

    else
    // Dealing with the positive/negative signs
    char firstChar = number.charAt(0);
    if (firstChar == MINUS_CHAR


    private boolean isNegative()
    return negative;


    private void flipNegativity()
    if (stringNumber == "0")
    return;

    negative = !negative;
    if (stringNumber.charAt(0) == MINUS_CHAR)
    stringNumber = stringNumber.substring(1);
    else
    stringNumber = MINUS_CHAR + stringNumber;



    // Adding another bigInt number to the current bigInt number
    BigInt plus(BigInt otherNumber)

    // current is negative, other is positive - subtract current from the other
    if (negative && !otherNumber.isNegative())
    return otherNumber.minus(new BigInt(stringNumber));


    // other is negative - subtract its value
    if (otherNumber.isNegative())
    return minus(new BigInt(otherNumber.toString()));


    // Setting the longer number of the two numbers
    ArrayList<Integer> longerNumber, shorterNumber;
    if (numberDigits.size() >= otherNumber.numberDigits.size())
    longerNumber = numberDigits;
    shorterNumber = otherNumber.numberDigits;

    else
    longerNumber = otherNumber.numberDigits;
    shorterNumber = numberDigits;


    int lengthsDifferences = longerNumber.size() - shorterNumber.size();


    StringBuilder resultString = new StringBuilder();

    // Initializing a carry for every addition
    int carry = 0;


    // Iterating from smallest unit digit to the biggest
    for (int index = shorterNumber.size() - 1; index >= 0; index--)
    int shorterNumberDigit = shorterNumber.get(index);
    int longerNumberDigit = longerNumber.get(index + lengthsDifferences);

    int newDigit = shorterNumberDigit + longerNumberDigit + carry;

    // Calculating the carry and the new digit
    carry = newDigit / 10;
    newDigit = newDigit % 10;

    resultString.append(newDigit);


    // Adding digits of longer number
    for (int index = lengthsDifferences - 1; index >= 0; index--)
    int currDig = longerNumber.get(index);

    // Check if need to add carry
    if (currDig + carry == 10)
    resultString.append(0);
    carry = 1;
    else
    resultString.append(currDig + carry);
    carry = 0;



    // Check if there is carry on last digit
    if (carry > 0)
    resultString.append(carry);

    return new BigInt(resultString.reverse().toString());


    BigInt minus(BigInt otherNumber)

    // If the other number is negative, add its value
    if (otherNumber.isNegative())
    return plus(new BigInt(otherNumber.stringNumber));


    // subtract a bigger number than the current
    if (this.compareTo(otherNumber) < 0)
    BigInt result = otherNumber.minus(this);
    result.flipNegativity();
    return result;


    // Other number is positive and not greater than current:
    int lengthsDifferences = numberDigits.size() - otherNumber.numberDigits.size();

    StringBuilder resultString = new StringBuilder();

    int carry = 0;

    for (int index = otherNumber.numberDigits.size() - 1; index >=0 ; index--)
    int biggerNumDig = numberDigits.get(index + lengthsDifferences) - carry;
    int smallerNumDig = otherNumber.numberDigits.get(index);

    carry = 0;

    if (biggerNumDig < smallerNumDig)
    carry = 1;
    biggerNumDig += 10;


    resultString.append(biggerNumDig - smallerNumDig);


    for (int index = lengthsDifferences - 1; index >=0 ; index--)
    int currDig = numberDigits.get(index);

    // Check if carry is needed
    if (carry > currDig)
    resultString.append(currDig + 10 - carry);
    carry = 1;
    else
    resultString.append(currDig - carry);
    carry = 0;



    return new BigInt(resultString.reverse().toString());


    // Multiply bigInt
    BigInt multiply(BigInt otherNumber) isNegative() && !otherNumber.isNegative())
    finalResult.flipNegativity();

    return finalResult;


    BigInt divide(BigInt otherNumber)

    if (isBigIntZero(otherNumber))
    throw new ArithmeticException();

    // Handling the case where the current number is positive and the other is negative
    if (otherNumber.isNegative() && !isNegative())
    BigInt result = divide(new BigInt(otherNumber.stringNumber));
    result.flipNegativity();
    return result;

    // Handling the case where the current number is negative and the other is positive
    else if (!otherNumber.isNegative() && isNegative())
    BigInt result = new BigInt(stringNumber).divide(otherNumber);
    result.flipNegativity();
    return result;


    int compareResult = this.compareTo(otherNumber);
    if (compareResult == 0)
    return new BigInt("1");
    else if (compareResult < 0)
    return new BigInt("0");

    BigInt result = new BigInt("0");
    BigInt tempNumber = new BigInt("0");

    while (tempNumber.compareTo(this) < 0)
    tempNumber = tempNumber.plus(otherNumber);
    result = result.plus(new BigInt("1"));


    return result;



    private boolean isBigIntZero(BigInt number)
    return number.stringNumber.replace("0", "").equals("");



    // Multiply a unit of BigInt with an integer. Example: 1000000000000000000 * 54
    private BigInt MultiplyUnit(int majorUnits)

    // Setting the string representation
    String majorUnitsString = String.valueOf(majorUnits);
    String newNumber = majorUnitsString + stringNumber.substring(1);

    return new BigInt(newNumber);


    private void multiplyByTen()
    this.numberDigits.add(0);
    stringNumber += '0';


    @Override
    public int compareTo(BigInt other)

    // Current is negative, other is positive
    if (isNegative() && !other.isNegative())
    return -1;

    // Current is positive, other is negative
    else if (!isNegative() && other.isNegative())
    return 1;


    // Both are negative
    else if (isNegative())
    // Current is negative and has more digits - therefore it is smaller
    if (numberDigits.size() > other.numberDigits.size())
    return -1;
    // Current is negative and has less digits - Therefore it is bigger
    else if (numberDigits.size() < other.numberDigits.size())
    return 1;

    // Both have same number of digits - need to iterate them
    else
    for (int index = 0; index < numberDigits.size(); index++)

    // Current has bigger negative digit - therefore it is smaller
    if (numberDigits.get(index) > other.numberDigits.get(index))
    return -1;

    // Current has smaller negative digit - therefore it is smaller
    else if (numberDigits.get(index) < other.numberDigits.get(index))
    return 1;


    // If we have reached here, the numbers are completely identical
    return 0;


    // If we have reached here, both numbers are positive

    // Current is positive and has more digits - Therefore it is bigger
    if (numberDigits.size() > other.numberDigits.size())
    return 1;


    // Current is positive and has less digits - Therefore it is smaller
    else if (numberDigits.size() < other.numberDigits.size())
    return -1;

    // Both have same number of digits - need to iterate them
    else
    for (int index = 0; index < numberDigits.size(); index++)

    // Current has bigger positive digit - therefore it is bigger
    if (numberDigits.get(index) > other.numberDigits.get(index))
    return 1;

    // Current has smaller positive digit - therefore it is smaller
    else if (numberDigits.get(index) < other.numberDigits.get(index))
    return -1;


    // If we have reached here, the numbers are completely identical
    return 0;


    @Override
    public boolean equals(Object o)
    // self check
    if (this == o)
    return true;

    // null check
    if (o == null)
    return false;

    // type check and cast
    if (getClass() != o.getClass())
    return false;

    BigInt other = (BigInt) o;
    // field comparison

    return other.toString().equals(stringNumber);


    @Override
    public String toString()
    return stringNumber;




    Main



    import com.sun.javaws.exceptions.InvalidArgumentException;

    import java.util.Scanner;

    public class Main

    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args)
    BigInt firstNumber;
    BigInt secondNumber;

    System.out.println("Enter first number: ");
    firstNumber = inputBigIntNumber();

    System.out.println("Enter second number: ");
    secondNumber = inputBigIntNumber();

    System.out.println("The result of plus is: " + firstNumber.plus(secondNumber));
    System.out.println("The result of minus is: " + firstNumber.minus(secondNumber));
    System.out.println("The result of multiply is: " + firstNumber.multiply(secondNumber));

    try
    System.out.println("The result of divide is: " + firstNumber.divide(secondNumber));
    catch (ArithmeticException ex)
    System.out.println("Can not divide by zero");




    // Taking a valid integer input from the user (greater than 0)
    private static BigInt inputBigIntNumber()

    String str = scanner.nextLine();

    while (true)
    try
    return new BigInt(str);

    catch (IllegalArgumentException ex)
    System.out.println("Invalid number, please try again: ");












    share









    $endgroup$














      0












      0








      0





      $begingroup$


      I've written a java application that can handle operations on big integers implemented with array list of digits.



      I have a difficulity with the way I implemented the divide method, because when the difference between the two numbers is high, the operation can take a huge amount of time.



      I'd like to hear your thoughts about this implementation and ways it can be improved. Here is the class and it's test class:



      BigInt.java



      import java.util.ArrayList;

      public class BigInt implements Comparable<BigInt>

      private static final char MINUS_CHAR = '-';
      private static final char PLUS_CHAR = '+';

      // Saves the digits of the number - last element represents the smallest unit of the number
      private ArrayList<Integer> numberDigits = new ArrayList<>();

      // Indication if the number is negative
      private boolean negative;

      // String representation as given by the user
      private String stringNumber;

      BigInt(String number)

      if (number.equals(""))
      stringNumber = "0";
      numberDigits.add(0);

      else
      // Dealing with the positive/negative signs
      char firstChar = number.charAt(0);
      if (firstChar == MINUS_CHAR


      private boolean isNegative()
      return negative;


      private void flipNegativity()
      if (stringNumber == "0")
      return;

      negative = !negative;
      if (stringNumber.charAt(0) == MINUS_CHAR)
      stringNumber = stringNumber.substring(1);
      else
      stringNumber = MINUS_CHAR + stringNumber;



      // Adding another bigInt number to the current bigInt number
      BigInt plus(BigInt otherNumber)

      // current is negative, other is positive - subtract current from the other
      if (negative && !otherNumber.isNegative())
      return otherNumber.minus(new BigInt(stringNumber));


      // other is negative - subtract its value
      if (otherNumber.isNegative())
      return minus(new BigInt(otherNumber.toString()));


      // Setting the longer number of the two numbers
      ArrayList<Integer> longerNumber, shorterNumber;
      if (numberDigits.size() >= otherNumber.numberDigits.size())
      longerNumber = numberDigits;
      shorterNumber = otherNumber.numberDigits;

      else
      longerNumber = otherNumber.numberDigits;
      shorterNumber = numberDigits;


      int lengthsDifferences = longerNumber.size() - shorterNumber.size();


      StringBuilder resultString = new StringBuilder();

      // Initializing a carry for every addition
      int carry = 0;


      // Iterating from smallest unit digit to the biggest
      for (int index = shorterNumber.size() - 1; index >= 0; index--)
      int shorterNumberDigit = shorterNumber.get(index);
      int longerNumberDigit = longerNumber.get(index + lengthsDifferences);

      int newDigit = shorterNumberDigit + longerNumberDigit + carry;

      // Calculating the carry and the new digit
      carry = newDigit / 10;
      newDigit = newDigit % 10;

      resultString.append(newDigit);


      // Adding digits of longer number
      for (int index = lengthsDifferences - 1; index >= 0; index--)
      int currDig = longerNumber.get(index);

      // Check if need to add carry
      if (currDig + carry == 10)
      resultString.append(0);
      carry = 1;
      else
      resultString.append(currDig + carry);
      carry = 0;



      // Check if there is carry on last digit
      if (carry > 0)
      resultString.append(carry);

      return new BigInt(resultString.reverse().toString());


      BigInt minus(BigInt otherNumber)

      // If the other number is negative, add its value
      if (otherNumber.isNegative())
      return plus(new BigInt(otherNumber.stringNumber));


      // subtract a bigger number than the current
      if (this.compareTo(otherNumber) < 0)
      BigInt result = otherNumber.minus(this);
      result.flipNegativity();
      return result;


      // Other number is positive and not greater than current:
      int lengthsDifferences = numberDigits.size() - otherNumber.numberDigits.size();

      StringBuilder resultString = new StringBuilder();

      int carry = 0;

      for (int index = otherNumber.numberDigits.size() - 1; index >=0 ; index--)
      int biggerNumDig = numberDigits.get(index + lengthsDifferences) - carry;
      int smallerNumDig = otherNumber.numberDigits.get(index);

      carry = 0;

      if (biggerNumDig < smallerNumDig)
      carry = 1;
      biggerNumDig += 10;


      resultString.append(biggerNumDig - smallerNumDig);


      for (int index = lengthsDifferences - 1; index >=0 ; index--)
      int currDig = numberDigits.get(index);

      // Check if carry is needed
      if (carry > currDig)
      resultString.append(currDig + 10 - carry);
      carry = 1;
      else
      resultString.append(currDig - carry);
      carry = 0;



      return new BigInt(resultString.reverse().toString());


      // Multiply bigInt
      BigInt multiply(BigInt otherNumber) isNegative() && !otherNumber.isNegative())
      finalResult.flipNegativity();

      return finalResult;


      BigInt divide(BigInt otherNumber)

      if (isBigIntZero(otherNumber))
      throw new ArithmeticException();

      // Handling the case where the current number is positive and the other is negative
      if (otherNumber.isNegative() && !isNegative())
      BigInt result = divide(new BigInt(otherNumber.stringNumber));
      result.flipNegativity();
      return result;

      // Handling the case where the current number is negative and the other is positive
      else if (!otherNumber.isNegative() && isNegative())
      BigInt result = new BigInt(stringNumber).divide(otherNumber);
      result.flipNegativity();
      return result;


      int compareResult = this.compareTo(otherNumber);
      if (compareResult == 0)
      return new BigInt("1");
      else if (compareResult < 0)
      return new BigInt("0");

      BigInt result = new BigInt("0");
      BigInt tempNumber = new BigInt("0");

      while (tempNumber.compareTo(this) < 0)
      tempNumber = tempNumber.plus(otherNumber);
      result = result.plus(new BigInt("1"));


      return result;



      private boolean isBigIntZero(BigInt number)
      return number.stringNumber.replace("0", "").equals("");



      // Multiply a unit of BigInt with an integer. Example: 1000000000000000000 * 54
      private BigInt MultiplyUnit(int majorUnits)

      // Setting the string representation
      String majorUnitsString = String.valueOf(majorUnits);
      String newNumber = majorUnitsString + stringNumber.substring(1);

      return new BigInt(newNumber);


      private void multiplyByTen()
      this.numberDigits.add(0);
      stringNumber += '0';


      @Override
      public int compareTo(BigInt other)

      // Current is negative, other is positive
      if (isNegative() && !other.isNegative())
      return -1;

      // Current is positive, other is negative
      else if (!isNegative() && other.isNegative())
      return 1;


      // Both are negative
      else if (isNegative())
      // Current is negative and has more digits - therefore it is smaller
      if (numberDigits.size() > other.numberDigits.size())
      return -1;
      // Current is negative and has less digits - Therefore it is bigger
      else if (numberDigits.size() < other.numberDigits.size())
      return 1;

      // Both have same number of digits - need to iterate them
      else
      for (int index = 0; index < numberDigits.size(); index++)

      // Current has bigger negative digit - therefore it is smaller
      if (numberDigits.get(index) > other.numberDigits.get(index))
      return -1;

      // Current has smaller negative digit - therefore it is smaller
      else if (numberDigits.get(index) < other.numberDigits.get(index))
      return 1;


      // If we have reached here, the numbers are completely identical
      return 0;


      // If we have reached here, both numbers are positive

      // Current is positive and has more digits - Therefore it is bigger
      if (numberDigits.size() > other.numberDigits.size())
      return 1;


      // Current is positive and has less digits - Therefore it is smaller
      else if (numberDigits.size() < other.numberDigits.size())
      return -1;

      // Both have same number of digits - need to iterate them
      else
      for (int index = 0; index < numberDigits.size(); index++)

      // Current has bigger positive digit - therefore it is bigger
      if (numberDigits.get(index) > other.numberDigits.get(index))
      return 1;

      // Current has smaller positive digit - therefore it is smaller
      else if (numberDigits.get(index) < other.numberDigits.get(index))
      return -1;


      // If we have reached here, the numbers are completely identical
      return 0;


      @Override
      public boolean equals(Object o)
      // self check
      if (this == o)
      return true;

      // null check
      if (o == null)
      return false;

      // type check and cast
      if (getClass() != o.getClass())
      return false;

      BigInt other = (BigInt) o;
      // field comparison

      return other.toString().equals(stringNumber);


      @Override
      public String toString()
      return stringNumber;




      Main



      import com.sun.javaws.exceptions.InvalidArgumentException;

      import java.util.Scanner;

      public class Main

      private static Scanner scanner = new Scanner(System.in);

      public static void main(String[] args)
      BigInt firstNumber;
      BigInt secondNumber;

      System.out.println("Enter first number: ");
      firstNumber = inputBigIntNumber();

      System.out.println("Enter second number: ");
      secondNumber = inputBigIntNumber();

      System.out.println("The result of plus is: " + firstNumber.plus(secondNumber));
      System.out.println("The result of minus is: " + firstNumber.minus(secondNumber));
      System.out.println("The result of multiply is: " + firstNumber.multiply(secondNumber));

      try
      System.out.println("The result of divide is: " + firstNumber.divide(secondNumber));
      catch (ArithmeticException ex)
      System.out.println("Can not divide by zero");




      // Taking a valid integer input from the user (greater than 0)
      private static BigInt inputBigIntNumber()

      String str = scanner.nextLine();

      while (true)
      try
      return new BigInt(str);

      catch (IllegalArgumentException ex)
      System.out.println("Invalid number, please try again: ");












      share









      $endgroup$




      I've written a java application that can handle operations on big integers implemented with array list of digits.



      I have a difficulity with the way I implemented the divide method, because when the difference between the two numbers is high, the operation can take a huge amount of time.



      I'd like to hear your thoughts about this implementation and ways it can be improved. Here is the class and it's test class:



      BigInt.java



      import java.util.ArrayList;

      public class BigInt implements Comparable<BigInt>

      private static final char MINUS_CHAR = '-';
      private static final char PLUS_CHAR = '+';

      // Saves the digits of the number - last element represents the smallest unit of the number
      private ArrayList<Integer> numberDigits = new ArrayList<>();

      // Indication if the number is negative
      private boolean negative;

      // String representation as given by the user
      private String stringNumber;

      BigInt(String number)

      if (number.equals(""))
      stringNumber = "0";
      numberDigits.add(0);

      else
      // Dealing with the positive/negative signs
      char firstChar = number.charAt(0);
      if (firstChar == MINUS_CHAR


      private boolean isNegative()
      return negative;


      private void flipNegativity()
      if (stringNumber == "0")
      return;

      negative = !negative;
      if (stringNumber.charAt(0) == MINUS_CHAR)
      stringNumber = stringNumber.substring(1);
      else
      stringNumber = MINUS_CHAR + stringNumber;



      // Adding another bigInt number to the current bigInt number
      BigInt plus(BigInt otherNumber)

      // current is negative, other is positive - subtract current from the other
      if (negative && !otherNumber.isNegative())
      return otherNumber.minus(new BigInt(stringNumber));


      // other is negative - subtract its value
      if (otherNumber.isNegative())
      return minus(new BigInt(otherNumber.toString()));


      // Setting the longer number of the two numbers
      ArrayList<Integer> longerNumber, shorterNumber;
      if (numberDigits.size() >= otherNumber.numberDigits.size())
      longerNumber = numberDigits;
      shorterNumber = otherNumber.numberDigits;

      else
      longerNumber = otherNumber.numberDigits;
      shorterNumber = numberDigits;


      int lengthsDifferences = longerNumber.size() - shorterNumber.size();


      StringBuilder resultString = new StringBuilder();

      // Initializing a carry for every addition
      int carry = 0;


      // Iterating from smallest unit digit to the biggest
      for (int index = shorterNumber.size() - 1; index >= 0; index--)
      int shorterNumberDigit = shorterNumber.get(index);
      int longerNumberDigit = longerNumber.get(index + lengthsDifferences);

      int newDigit = shorterNumberDigit + longerNumberDigit + carry;

      // Calculating the carry and the new digit
      carry = newDigit / 10;
      newDigit = newDigit % 10;

      resultString.append(newDigit);


      // Adding digits of longer number
      for (int index = lengthsDifferences - 1; index >= 0; index--)
      int currDig = longerNumber.get(index);

      // Check if need to add carry
      if (currDig + carry == 10)
      resultString.append(0);
      carry = 1;
      else
      resultString.append(currDig + carry);
      carry = 0;



      // Check if there is carry on last digit
      if (carry > 0)
      resultString.append(carry);

      return new BigInt(resultString.reverse().toString());


      BigInt minus(BigInt otherNumber)

      // If the other number is negative, add its value
      if (otherNumber.isNegative())
      return plus(new BigInt(otherNumber.stringNumber));


      // subtract a bigger number than the current
      if (this.compareTo(otherNumber) < 0)
      BigInt result = otherNumber.minus(this);
      result.flipNegativity();
      return result;


      // Other number is positive and not greater than current:
      int lengthsDifferences = numberDigits.size() - otherNumber.numberDigits.size();

      StringBuilder resultString = new StringBuilder();

      int carry = 0;

      for (int index = otherNumber.numberDigits.size() - 1; index >=0 ; index--)
      int biggerNumDig = numberDigits.get(index + lengthsDifferences) - carry;
      int smallerNumDig = otherNumber.numberDigits.get(index);

      carry = 0;

      if (biggerNumDig < smallerNumDig)
      carry = 1;
      biggerNumDig += 10;


      resultString.append(biggerNumDig - smallerNumDig);


      for (int index = lengthsDifferences - 1; index >=0 ; index--)
      int currDig = numberDigits.get(index);

      // Check if carry is needed
      if (carry > currDig)
      resultString.append(currDig + 10 - carry);
      carry = 1;
      else
      resultString.append(currDig - carry);
      carry = 0;



      return new BigInt(resultString.reverse().toString());


      // Multiply bigInt
      BigInt multiply(BigInt otherNumber) isNegative() && !otherNumber.isNegative())
      finalResult.flipNegativity();

      return finalResult;


      BigInt divide(BigInt otherNumber)

      if (isBigIntZero(otherNumber))
      throw new ArithmeticException();

      // Handling the case where the current number is positive and the other is negative
      if (otherNumber.isNegative() && !isNegative())
      BigInt result = divide(new BigInt(otherNumber.stringNumber));
      result.flipNegativity();
      return result;

      // Handling the case where the current number is negative and the other is positive
      else if (!otherNumber.isNegative() && isNegative())
      BigInt result = new BigInt(stringNumber).divide(otherNumber);
      result.flipNegativity();
      return result;


      int compareResult = this.compareTo(otherNumber);
      if (compareResult == 0)
      return new BigInt("1");
      else if (compareResult < 0)
      return new BigInt("0");

      BigInt result = new BigInt("0");
      BigInt tempNumber = new BigInt("0");

      while (tempNumber.compareTo(this) < 0)
      tempNumber = tempNumber.plus(otherNumber);
      result = result.plus(new BigInt("1"));


      return result;



      private boolean isBigIntZero(BigInt number)
      return number.stringNumber.replace("0", "").equals("");



      // Multiply a unit of BigInt with an integer. Example: 1000000000000000000 * 54
      private BigInt MultiplyUnit(int majorUnits)

      // Setting the string representation
      String majorUnitsString = String.valueOf(majorUnits);
      String newNumber = majorUnitsString + stringNumber.substring(1);

      return new BigInt(newNumber);


      private void multiplyByTen()
      this.numberDigits.add(0);
      stringNumber += '0';


      @Override
      public int compareTo(BigInt other)

      // Current is negative, other is positive
      if (isNegative() && !other.isNegative())
      return -1;

      // Current is positive, other is negative
      else if (!isNegative() && other.isNegative())
      return 1;


      // Both are negative
      else if (isNegative())
      // Current is negative and has more digits - therefore it is smaller
      if (numberDigits.size() > other.numberDigits.size())
      return -1;
      // Current is negative and has less digits - Therefore it is bigger
      else if (numberDigits.size() < other.numberDigits.size())
      return 1;

      // Both have same number of digits - need to iterate them
      else
      for (int index = 0; index < numberDigits.size(); index++)

      // Current has bigger negative digit - therefore it is smaller
      if (numberDigits.get(index) > other.numberDigits.get(index))
      return -1;

      // Current has smaller negative digit - therefore it is smaller
      else if (numberDigits.get(index) < other.numberDigits.get(index))
      return 1;


      // If we have reached here, the numbers are completely identical
      return 0;


      // If we have reached here, both numbers are positive

      // Current is positive and has more digits - Therefore it is bigger
      if (numberDigits.size() > other.numberDigits.size())
      return 1;


      // Current is positive and has less digits - Therefore it is smaller
      else if (numberDigits.size() < other.numberDigits.size())
      return -1;

      // Both have same number of digits - need to iterate them
      else
      for (int index = 0; index < numberDigits.size(); index++)

      // Current has bigger positive digit - therefore it is bigger
      if (numberDigits.get(index) > other.numberDigits.get(index))
      return 1;

      // Current has smaller positive digit - therefore it is smaller
      else if (numberDigits.get(index) < other.numberDigits.get(index))
      return -1;


      // If we have reached here, the numbers are completely identical
      return 0;


      @Override
      public boolean equals(Object o)
      // self check
      if (this == o)
      return true;

      // null check
      if (o == null)
      return false;

      // type check and cast
      if (getClass() != o.getClass())
      return false;

      BigInt other = (BigInt) o;
      // field comparison

      return other.toString().equals(stringNumber);


      @Override
      public String toString()
      return stringNumber;




      Main



      import com.sun.javaws.exceptions.InvalidArgumentException;

      import java.util.Scanner;

      public class Main

      private static Scanner scanner = new Scanner(System.in);

      public static void main(String[] args)
      BigInt firstNumber;
      BigInt secondNumber;

      System.out.println("Enter first number: ");
      firstNumber = inputBigIntNumber();

      System.out.println("Enter second number: ");
      secondNumber = inputBigIntNumber();

      System.out.println("The result of plus is: " + firstNumber.plus(secondNumber));
      System.out.println("The result of minus is: " + firstNumber.minus(secondNumber));
      System.out.println("The result of multiply is: " + firstNumber.multiply(secondNumber));

      try
      System.out.println("The result of divide is: " + firstNumber.divide(secondNumber));
      catch (ArithmeticException ex)
      System.out.println("Can not divide by zero");




      // Taking a valid integer input from the user (greater than 0)
      private static BigInt inputBigIntNumber()

      String str = scanner.nextLine();

      while (true)
      try
      return new BigInt(str);

      catch (IllegalArgumentException ex)
      System.out.println("Invalid number, please try again: ");










      java beginner





      share












      share










      share



      share










      asked 2 mins ago









      S. PeterS. Peter

      163311




      163311




















          0






          active

          oldest

          votes












          Your Answer





          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216513%2fjava-biginteger-implementation%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216513%2fjava-biginteger-implementation%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

          Prove that NP is closed under karp reduction?Space(n) not closed under Karp reductions - what about NTime(n)?Class P is closed under rotation?Prove or disprove that $NL$ is closed under polynomial many-one reductions$mathbfNC_2$ is closed under log-space reductionOn Karp reductionwhen can I know if a class (complexity) is closed under reduction (cook/karp)Check if class $PSPACE$ is closed under polyonomially space reductionIs NPSPACE also closed under polynomial-time reduction and under log-space reduction?Prove PSPACE is closed under complement?Prove PSPACE is closed under union?

          Is my guitar’s action too high? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Strings too stiff on a recently purchased acoustic guitar | Cort AD880CEIs the action of my guitar really high?Μy little finger is too weak to play guitarWith guitar, how long should I give my fingers to strengthen / callous?When playing a fret the guitar sounds mutedPlaying (Barre) chords up the guitar neckI think my guitar strings are wound too tight and I can't play barre chordsF barre chord on an SG guitarHow to find to the right strings of a barre chord by feel?High action on higher fret on my steel acoustic guitar