1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Java adding two objects

  1. Sep 12, 2011 #1
    Thers a class called BigInt and it has a size and digit. size is the number of digits in the integer that is entered and digit is an array that holds the integer.

    Theres a method in the class called plus which is supposed to add two BigInts together. If there is a remainder the remainder is supposed to carry over like in regular addition.

    This is how the numbers are passed from the main class to the BigInt Class.
    num2 = num.plus(num1);

    Below is the method that im working on right now to add the two BigInts.

    public BigInt plus(BigInt arg) { // add two BigIntís
    BigInt number = arg;
    BigInt sum = new BigInt();
    sum.digit = new int[50];
    int remainder = 0;
    for(int i = 0; i <= size; i++)
    sum.digit = this.digit + number.digit + remainder;


    return sum;

    }
    I'm not even sure if i passed in the number correctly. or if i made the sum array correctly.

    I know that the for loop is going to be used to add the two BigInts but im not sure where they start or where they end because im not sure about what im passing into this method.

    Was i right when i said this.digit?

    I know there has to be a mod in an if statement that gives remainder a new value if the sum is greater than 9. I just wanted to get this rough method to print something out before i went any further.

    any help would be appreciated. If needed, i can add the entire main class and BigInt Class for clarity.
     
  2. jcsd
  3. Sep 12, 2011 #2

    Mark44

    Staff: Mentor

    When you enter code in a post, put (code) and (/code) tags around it (but use brackets - [ and ], not parentheses). I have done this with your code.

    This will preserve your indentation, and can help make the code easier to read.
    Yeah, you passed the number correctly, but you don't need an extra local variable to hold it. I.e., you don't need "number". The parameter "arg" already has the number in it.

    You do need a variable for the sum, which you have in the 2nd line of code.

    In your 3rd line of code, you are assuming that there will be no more than 50 digits in the sum? Is that a reasonable assumption? You didn't give any information as to limitations on the size of a BigInt.

    Your for loop won't work correctly, as you are adding from the wrong end. When you add two integers together, you start by adding the 1's place of both numbers, then the 10's place, and so on. Your code starts from the other end.

    Also, there is no guarantee that both numbers to be added have the same number of digits. For example, if you were adding 123456789 and 1111, your code would get 234556789, which is incorrect. Instead what you need to to is add 9 and 1 (which gives you a carry), and then 8 and 1 plus the carry, and so on, moving right to left until you run out of digits.

    Finally, what you are calling "remainder" is usually called the carry. The term "remainder" implies that division is going on, not addition. Your code sets remainder to 0, and then never resets it to any other value, so inside the loop you will always be adding 0.

    To fix your code, manually (with paper and pencil) go through the steps of adding two numbers together. That should give you a better idea of what your routine needs to do.




    Yes. Each time you add two digits, there should be an if statement to check to see whether the sum of those two digits was greater than 9. If so, you will need to carry 1 to the next higher place.
     
  4. Sep 12, 2011 #3
    The BigInt wont be bigger than 50 digits.

    I know that my for loop is wrong. I tried to just have it start at 50 and end at 0 but it gave me an out of bounds error: "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 50

    What i was thinking of doing was comparing the size of the two BigInts. Could i just do that by writing an if statement that would compare this.size and arg.size to see which one is bigger and then set the for loop to start at this.size(if it turned out to be bigger) and end at 0?


    This is what i have so far

    Code (Text):
     public BigInt plus(BigInt arg) { // add two BigIntís
           
            BigInt sum = new BigInt();
            sum.digit = new int[50];
            int carry = 0;
                for(int i = 50; i > 0; i--){
                   
                    sum.digit[i] = this.digit[i] + arg.digit[i] + carry;//adds two BigInts and possible carry
                        if(sum.digit[i] > 9){ //to extract carry if the sum is greater than 9
                        sum.digit[i] = sum.digit[i] % 10;//extract the ones place
                        carry = sum.digit[i] / 10;//extract the carry
                        }
                       
                    }  
           
            return sum;
           
        }
     
  5. Sep 12, 2011 #4

    Mark44

    Staff: Mentor

    If your array has 50 numbers in it, the indexes run from 0 through 49. Trying to access the element at index 50 is what caused the exception you got.

    What you have looks pretty close. Change your loop to
    for (int i = 49; i >= 0; i--)

    BTW, I formatted your code to make it a little more readable, mostly by undoing some of the indentation you have, which makes your code spread way to the right on the page here.
    Code (Text):

    public BigInt plus(BigInt arg)
    { // add two BigIntís
           
       BigInt sum = new BigInt();
       sum.digit = new int[50];
       int carry = 0;
       for(int i = 50; i > 0; i--)
       {
          sum.digit[i] = this.digit[i] + arg.digit[i] + carry;//adds two BigInts and possible carry
          if(sum.digit[i] > 9){ //to extract carry if the sum is greater than 9
             sum.digit[i] = sum.digit[i] % 10;//extract the ones place
             carry = sum.digit[i] / 10;//extract the carry
          }
                       
       }   
       return sum;
    }
     
     
  6. Sep 13, 2011 #5
    i made that change. it adds the digits in the ones place but thats all it does. I havent figured out why it does that. Also, if i add 999 + 1 it returns 990. Should i create an if statement or something that does the carry for everything except the first element so that it can become 1000?
     
  7. Sep 13, 2011 #6

    Mark44

    Staff: Mentor

    You already have an if statement.

    You are calculating the carry value too late. All you need to do is reverse the order of the two statements in your if statement.
     
  8. Sep 13, 2011 #7
    I can add as long as the sum is less than 1000, if the sum is over 1000. if i set the first number equal to 800 and the second number equal to 201 it gives me 012 as the sum. But if i put in 800 and 151, for example, 951 will print out as the sum.

    This is what i changed it to

    Code (Text):
     public BigInt plus(BigInt arg) { // add two BigInt’s
           
            BigInt sum = new BigInt();//Create sum object
            int carry = 0; //declare and intialize carry
            int i;
            //change size of sum
            if(this.size > arg.size)
                sum.size = this.size;
            else
                sum.size = arg.size;
           
            //add two BigInts
           
                for(i = sum.size - 1; i >= 0; i--){
                    sum.digit[i] = this.digit[i] + arg.digit[i] + carry;
                   
                    if(sum.digit[i] > 9){
                    carry = sum.digit[i] / 10;
                    sum.digit[i] = sum.digit[i] % 10;
                       
                    }//closes if
                    else{
                    sum.digit[i] = sum.digit[i];
                    }
                }//closes for
           
            return sum;
           
        }//closes plus
     
  9. Sep 13, 2011 #8

    Mark44

    Staff: Mentor

    I reformatted your code, as it was indented too much, and I had to scroll across to see the ends of some lines. Don't indent the top line of a for loop - just the body.
    Your code is different from what you posted before, particularly the part where you are fiddling with the size of the argument. You should not be doing this. It will often be the case that sum will have more digits in it than either of the two numbers being added together. Think about the example you gave, where you're adding together 800 and 201. The sum is 1001. Your answer of 021 indicates at least two problems: sum is being truncated, and your addition is wrong as well, possibly because you have three lines of code where sum.digit is being written to. You should be doing that only once.

    Here's some pseudocode for what each iteration of your loop should be doing. The <-- symbol means "is set to".
    Code (Text):
    temp <-- this.digit[i] + arg.digit[i] + carry
    sum.digit[i] <-- temp % 10
    carry <-- temp / 10
     
  10. Sep 13, 2011 #9
    This is what i changed it to. Now when it runs i get this message:
    Exception in thread "main" java.lang.NullPointerException
    at BigInt.plus(BigInt.java:69)
    at BigIntTest.main(BigIntTest.java:28)

    Whats that?




    Code (Text):
    public BigInt plus(BigInt arg) { // add two BigIntís
           
            BigInt sum = new BigInt();//Create sum object
            int carry = 0; //declare and intialize carry
            int i, temp;
           
           
            //add two BigInts
           
            for(i = 49; i >= 0; i--){
                    temp = this.digit[i] + arg.digit[i] + carry;
                   
                if(temp > 9){
                sum.digit[i] = temp % 10;
                carry = temp / 10; 
                }//closes if
                else{
                sum.digit[i] = temp;
                }
            }//closes for
           
        return sum;
           
    }//closes plus
     
  11. Sep 13, 2011 #10

    Mark44

    Staff: Mentor

    I don't know why you're getting that exception. There is something going on at line # 69 in your plus method, and at line #28 in your main method.

    Show me all of your code and I'm sure we can figure it out.
     
  12. Sep 13, 2011 #11
    This is the main
    Code (Text):
    public class BigIntTest {

       public static void main(String[] args) {
          int count, i;
          BigInt num, num1, num2 = new BigInt("1");
          BigInt zero = new BigInt();
          System.out.print("First BigInt's: " + new BigInt(233334));
          System.out.print(", " + new BigInt("567"));
          System.out.print(", " + new BigInt(230));
          System.out.print(", " + new BigInt("0"));
          System.out.println(", " + num2 + ", " + zero);
          System.out.println();
          // plus tester
            num = new BigInt(999);
          num1 = new BigInt(1);
          num2 = new BigInt(num);
           
            //Test bigInts
            System.out.println("Num " + num);
            System.out.println("Num1 " + num1);
            System.out.println("Num2 " + num2);
           
            System.out.println("\n Num + num1= " + num.plus(num1));
           
           
          for (count = 1; count <= 188; count++){    
             
                num2 = num.plus(num1);
             num = new BigInt(num1);
             num1 = new BigInt(num2);
             //num1.inc();
             //num2.inc();
             //num.inc();
             if (count <= 13)
                System.out.print(num1 + " ");
             else
                if (count % 50 == 38) {
                   System.out.println();
                   System.out.print(num1);
                }
          }
          System.out.println();
          System.out.println();
           // times tester
          BigInt[] val = new BigInt[3];
          BigInt temp;
          val[0] = new BigInt(95);
          temp = new BigInt(95);
          for (i = 1; i<= 10; i++) {
             for (count = 1; count <= 4; count++)
                val[0] = val[0].times(val[0]);
             System.out.println(val[0]);
             val[0] = temp.plus(new BigInt(i));
          }
          val[0] = new BigInt(1);
          val[1] = new BigInt(2);
          val[2] = new BigInt(3);
          for (count = 1; count <= 26; count++){
             if (count%2 == 0)
                val[0] = val[0].plus(val[1]);
             else
                val[0] = val[0].times(val[1]);
             if ((val[1].compareTo(val[0]) < 0) && (val[1].compareTo(val[2]) < 0)) {
                temp = val[1];
                val[1] = val[0];
                val[0] = temp;
             } else if ((val[2].compareTo(val[0]) < 0) && (val[2].compareTo(val[1]) < 0)) {
                temp = val[2];
                val[2] = val[0];
                val[0] = temp;
             }
             if (val[1].compareTo(val[2]) > 0) {
                temp = val[1];
                val[1] = val[2];
                val[2] = temp;
             }
             if (count <= 16) {
                System.out.print(val[0] + "  ");
                System.out.print(val[1] + "  ");
                System.out.print(val[2]);
             } else {
                System.out.println(val[0]);
                System.out.println(val[1]);
                System.out.println(val[2]);
             }
             System.out.println();
          }
          System.out.println();
       }
    }
    and this is the BigInt class

    Code (Text):
    class BigInt {
       private int digit[];         // represent the integer as an array of digits
       private int size;            // number of digits in the integer
       private final int max = 50;  // maximum number of digits in the integer
       public BigInt() {     // default constructor
        size = 1;
            digit = new int[max];
            digit[0] = 0;
     
       }
       public BigInt(String num) {  // constructor with initial String value
          size = num.length();
          digit = new int[max];
          for (int ct = size - 1; ct >= 0; ct --) {
             digit[ct] = Integer.parseInt(num.substring(size - ct - 1, size - ct));
          }
       }
       public BigInt(int num) {  // constructor with initial integer value
        size = Integer.toString(num).length();
        digit = new int[max];
            int rem = num;
            for ( int ct = 0; ct <= size - 1; ct++){
                digit[ct] = rem % 10;
                rem = rem / 10;
                }
       }
       public BigInt(BigInt num) {  // copy constructor
       BigInt copy = new BigInt();//Create copy object
        copy.size = this.size;//declare and initialize with BigInt nums size
        for(int i = 0; i < this.size; i++)//copy the digits in each index
            copy.digit[i] = this.digit[i];
       
       
        }
       public String toString() { // override Objectís version
          String intString = "";
          for (int ct = size - 1; ct >= 0; ct --) {
             intString = intString + String.valueOf(digit[ct]);
          }
          return intString;
       }
       public int compareTo(BigInt other) {
           int compare = 0;
             
            // return  1 if this greater than other
               
            // return -1 if this less than other
               
            // return  0 if both equal
               
           
        return compare;//must change                                 
                                           
        }
       public BigInt plus(BigInt arg) { // add two BigIntís
           
            BigInt sum = new BigInt();//Create sum object
            int carry = 0; //declare and intialize carry
            int i, temp;
           
           
            //add two BigInts
           
            for(i = 49; i >= 0; i--){
                temp = this.digit[i] + arg.digit[i] + carry;
                   
                if(temp > 9){
                sum.digit[i] = temp % 10;
                carry = temp / 10; 
                }//closes if
                else{
                sum.digit[i] = temp;
                }
            }//closes for
           
        return sum;
           
    }//closes plus
       
       
       public BigInt times(BigInt other) { // multiply two BigInts
       BigInt product = new BigInt();
       
       
        return product;
        }
       
       
       //private void times10() { // I found this useful, but you might not.
                              // Not required, but if you do write it be careful
                                // since it changes the BigInt. You might prefer  
                                // writing a version that creates a new BigInt
       }



    //inc method adds 1 to bigint
     
  13. Sep 13, 2011 #12

    Mark44

    Staff: Mentor

    Your BigIntTest file is way too complicated - you're trying to do too many things with stuff that is completely untested and buggy.

    BigIntTest.java - first 40 or so lines. Line 28 is marked
    Code (Text):
    public class BigIntTest {

       public static void main(String[] args) {
          int count, i;
          BigInt num, num1, num2 = new BigInt("1");
          BigInt zero = new BigInt();
          System.out.print("First BigInt's: " + new BigInt(233334));
          System.out.print(", " + new BigInt("567"));
          System.out.print(", " + new BigInt(230));
          System.out.print(", " + new BigInt("0"));
          System.out.println(", " + num2 + ", " + zero);
          System.out.println();
          // plus tester
            num = new BigInt(999);
          num1 = new BigInt(1);
          num2 = new BigInt(num);
           
            //Test bigInts
            System.out.println("Num " + num);
            System.out.println("Num1 " + num1);
            System.out.println("Num2 " + num2);
           
            System.out.println("\n Num + num1= " + num.plus(num1));
           
           
          for (count = 1; count <= 188; count++){    
             
    (28)            num2 = num.plus(num1);
             num = new BigInt(num1);
             num1 = new BigInt(num2);
             //num1.inc();
             //num2.inc();
             //num.inc();
             if (count <= 13)
                System.out.print(num1 + " ");
             else
                if (count % 50 == 38) {
                   System.out.println();
                   System.out.print(num1);
                }
          }
    Why do you have the random indentation? It makes it much more difficult to read your code when the blocks of code jump around all over the place. The only time you should change the indentation is when something unusual, such as a loop or an if block, is happening.
    Why is line 28 in a loop that is going to run 188 times?

    I would get rid of all of this and start fresh. Declare three BigNum variables, and initialize two of them like so:
    Code (Text):

    BigNum num1 = new BigNum(800);
    BigNum num2 = new BigNum(201);
    BigNum num3 = new BigNum();

    num3 = num1.plus(num2);
     
    What does this give you?
     
  14. Sep 13, 2011 #13
    that was a program that my professor gave us to test the BigInt class

    I made a new main class

    Code (Text):
    public class BigIntSimpleTest {

        public static void main(String[] args){

        BigInt num1 = new BigInt(800);
        BigInt num2 = new BigInt(201);
        BigInt num3 = new BigInt();
       
        num3 = num1.plus(num2);
        System.out.println("Num1 + Num2 = " + num3);
       
        }
    }
    but that prints out as 2 which make no sense
     
  15. Sep 13, 2011 #14

    Mark44

    Staff: Mentor

    The new code should be using this constructor for num1 and num2.
    Code (Text):

       public BigInt(int num) {  // constructor with initial integer value
        size = Integer.toString(num).length();
        digit = new int[max];
        int rem = num;
        for ( int ct = 0; ct <= size - 1; ct++){
           digit[ct] = rem % 10;
           rem = rem / 10;
        }
       }
     
    This code is not working right. It's storing numbers backwards and at the wrong end of the array. For example, the call to BigInt(800) creates an array of digits that looks like this, with the top row being the indexes of the array elements.
    0|1|2|3|4| ... |49
    0-0-8-0-0-...-0

    I don't remember whether Java initializes variables to a default value, so it might be that the array looks like this
    0|1|2|3|4| ... |49
    0-0-8-@-#-...-&
    Here, everything except the 2 zeroes and the 8 is a garbage value.

    I would think you want the digits in the array like this:
    0|1|2 ... 47|48|49
    0-0-0-... -8-0-0
     
  16. Sep 14, 2011 #15
    I see that the numbers are being reversed. I put two print statements for num1 and num2. num1 prints out as 008 and num2 prints out as 102.

    what i dont get is why its doing that because i changed the constructor

    Code (Text):
      public BigInt(int num) {  // constructor with initial integer value
        size = Integer.toString(num).length();
        digit = new int[max];
           
            for ( int ct = size - 1; ct >= 0; ct--){
                digit[ct] = num % 10;
                num = num / 10;
                }
       }
    if i understand correctly the loop should mod num so that the ones place of the integer goes into the last index of the array but its not doing that.
     
  17. Sep 14, 2011 #16

    Mark44

    Staff: Mentor

    Your indentation could still use some work. There are more or less standard ways of doing things.

    The top line of the for loop SHOULD NOT BE INDENTED, but the body of the loop should be, and the closing brace of the loop should be aligned with the for.
    The constructor above should be working, so it's possible that the reversal is happening somewhere else. Here's how you can test this.
    Code (Text):
    public class BigIntSimpleTest {

        public static void main(String[] args){

        BigInt num1 = new BigInt(800);
                 System.out.println("num1 digits = " + num1.digits); // added
        BigInt num2 = new BigInt(201);
        System.out.println("num2 digits = " + num2.digits); // added
        BigInt num3 = new BigInt();
       
        num3 = num1.plus(num2);
        System.out.println("Num1 + Num2 = " + num3);
       
        }
    }
     
    The reason I'm doing this is to see what's in the digits array right after each of the BigNum objects have been created, and looking directly at the array contents. My thought is that when you use print to display a BigNum, it might be that the copy constructor is being called, and I want to narrow things down as much as possible.

    If you have a debugger available, and know how to use it, that would be very helpful.

    A last comment - since your digit arrays have 50 elements, it would be a very good idea to initialize them before using them. If you don't initialize a variable, its value is whatever garbage happens to be in memory at the time, and that's not good.
     
  18. Sep 14, 2011 #17
    I played around with it and got it to work somehow. it just doesnt work if i want the sum to be greater than 9999. i get an arrayindexoutofboundsexception. i have to play with that to see why its happeneing.

    this is my constructor
    Code (Text):
     public BigInt(int num) {  // constructor with initial integer value
            size = Integer.toString(num).length();
            digit = new int[max];
           
            for ( int ct = 0; ct <= size-1; ct++){
                digit[ct] = num % 10;
                num = num / 10;
            }
       }
    and this is my plus method

    Code (Text):
    public BigInt plus(BigInt arg) { // add two BigInt’s
           
            BigInt sum = new BigInt();//Create sum object
             //declare and intialize carry
            int carry = 0; 
            int i, temp;
            //change size of sum
            if(this.size > arg.size)
                sum.size = this.size;
            else
                sum.size = arg.size;
           
            //add two BigInts
           
            for(i = 0; i <= sum.size-1; i++){
               
                    temp = this.digit[i] + arg.digit[i];
                temp = temp + carry;
                System.out.println(i + " Temp is " + temp);
               
                sum.digit[i] = temp % 10;
                carry = temp / 10;
                   
                if(temp > 9){
                while(sum.digit[i] == sum.digit[sum.size-1]){
                sum.size++;
                System.out.println("The while loop works when i is " + i);
                    }
                }
            System.out.println(i + "Carry is " + carry);
            System.out.println("sum.digit[" + i +"] is " + sum.digit[i]);      
            }//closes for
           
            return sum;
           
        }//closes plus
     
  19. Sep 14, 2011 #18

    Mark44

    Staff: Mentor

    There's a problem with your copy constructor. Here's your code:
    Code (Text):
    public BigInt(BigInt num) {  // copy constructor
       BigInt copy = new BigInt();//Create copy object
        copy.size = this.size;//declare and initialize with BigInt nums size
        for(int i = 0; i < this.size; i++)//copy the digits in each index
            copy.digit[i] = this.digit[i];
       
       
        }
     
    Your code is creating a local object named copy - it should not do this. What it should do is set the class member variables using the member variables on the parameter object, num.

    Here's some code - I don't have a Java compiler installed, so I can't guarantee that it will work perfectly, but it's a step in the right direction.

    Note how I am indenting things. This is a common style, including always using braces for for loops, even when the loop body is only one line. At the company where I work, this is how they do things.

    Code (Text):
    // Copy constructor
    public BigInt(BigInt num)
    {  
       // Copy member variables from num.
       size = num.size;
       // Copy the digits in each index.
       for(int i = 0; i < this.size; i++)
       {
          digit[i] = num.digit[i];
       }
    }
     
     
  20. Sep 14, 2011 #19
    is that because the object itself is being created in the main class?

    and sorry about the indentation, its been two years since ive done java and im just starting up again so im a little rusty.
     
  21. Sep 14, 2011 #20

    Mark44

    Staff: Mentor

    I don't understand your question. Are you asking about the copy constructor?
    I didn't notice an earlier post from you, where you said that things are working, except for numbers larger than 9999 - something like that.

    I'll take a look and reply back to that post.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook