Exit on first activation

So I’ve got a method that needs to exit on the first activation of a if statement. Here’s the code:

private int compareBigInts(BigInt aNumber, BigInt other){
        for(int i = aNumber.bigNum.size(); i > 0; i--) {
                if (aNumber.bigNum.get(i) > other.bigNum.get(i)) {
                  // aNumber is larger
                        return 1;
                }
                else  if(aNumber.bigNum.get(i) < other.bigNum.get(i)){
                  // other is larger
                        return -1;
                }
                else {
                  // other and aNumber are equal
                  return 0;
                }

        }
}

The problem is, Java does not like it when you have nested return statements.

If we use a variable to store the value of true and false then the problem becomes that the program only checks the least significant value. Eg. If we we’re comparing 1000 and 0010 they would be considered equal since at .get(0) place both contain zero.

What would be the safest way to implement this code?

PS: My numbers are scanned in backwards and are always the same length since zeros are added to the front of the integer beforehand.

I don’t find anything wrong with multiple return statements, and even goto's when used where they make sense.

But, what you could do is:

private int compareBigInts(BigInt aNumber, BigInt other){
        int ret = 0;

        for(int i = aNumber.bigNum.size(); i > 0; i--) {
                if (aNumber.bigNum.get(i) > other.bigNum.get(i)) {
                  // aNumber is larger
                        ret = 1;
                        break;
                }
                else  if(aNumber.bigNum.get(i) < other.bigNum.get(i)){
                  // other is larger
                        ret =  -1;
                        break;
                }
                else{
                        ret = 0;
                        break;
               }
        }

        return ret;
}
2 Likes

Okay that fixed my problem. I was not aware break existed. Thank you. :smiley:

3 Likes

I’m still wonder if I understand situation correctly, but lets go with this:

It surprisingly takes a lot of time to decipher your conversation because I kind of get a picture of “a blind describing the sunset to the deaf”. And I still get the feeling that I unknowingly comment in serious conversation between secret agents obfuscating the true meaning :wink:

The statement about return clause/keyword is not true. However I get that you meant something like “my usage of return (my algorithm) does not provide result I want”.
Then the presented solution with the break keyword actually change nothing in that regards.

I do not get if the higher index stores the most significant value, or the least one. So I will just state that the loop should start with the most significant value/digit and finish with the least significant value/digit (so adjust accordingly).

private int compareBigInts(BigInt aNumber, BigInt other){
  for(int i = aNumber.bigNum.size(); i > 0; i--) {		
    int comparison = Integer.compare(aNumber.bigNum.get(i), other.bigNum.get(i));				
    if ( comparison != 0 ) {
      return comparison;				
    }
  }
  return 0; // are the same
}

The code I have works now. Here’s the final result:

public int compareBigInts(BigInt aNumber, BigInt other){
    aNumber.addZerosIfNeeded(other);
    int ret = 0;
    if (aNumber.isNegative == true && other.isNegative == false) {
            ret = -1;
    }
    else if (aNumber.isNegative == false && other.isNegative == true) {
            ret = 1;
    }
    else{
            for(int i = aNumber.bigNum.size()-1; i > 0; i--) {
                    if (aNumber.bigNum.get(i) > other.bigNum.get(i)) {
                            // aNumber is larger
                            ret = 1;
                            break;
                    }
                    else if(aNumber.bigNum.get(i) < other.bigNum.get(i)) {
                            // other is larger
                            ret = -1;
                            break;
                    }
            }
    }

    return ret;
}

Unfortunately probably not, in general you forgot about one thing.

But first lets start with the negative sign:

  int signComparision = Boolean.compare(!aNumber.isNegative, !other.isNegative)	
  if ( signComparision!=0) {
	 return signComparision;
  }

You might just remove both negations (!) in case I’m to tired and it returns reverse of -1 and 1.

And the thing that you forgot and I did not included in my original response since I was not aware that you will have signs, is that:
-40 > -50 while 4<5
The the loop result -1/1 should be reversed if we are comparing negative values. Or simply reverse order of compared elements.
With the usage of (boolean/condition) ? valueIfTrue : valueIfFalse ;

int comparison = aNumber.isNegative? 
   Integer.compare(other.bigNum.get(i), aNumber.bigNum.get(i))    : 
   Integer.compare(aNumber.bigNum.get(i), other.bigNum.get(i));

PS. In general I assume from the beginning that we are doing this as a exercise (because BigInteger is part of Java).

1 Like

Sorry for being so curt earlier, I had not eaten anything and had been staring at my code for hours on end.

I did not thing about this case yet. Thank you for pointing it out.

This looks a lot more readable than what I was originally doing so I’ll put this in if I get the chance

At the moment I’m having more issues with my divide method than anything else.

My divide method is very slow and struggles when dividing large numbers (main reason I was just so angry earlier) :

If you want, have a look at the divide method, 'cause I’m not sure on how to make it any smaller.

Linking to new thread.

As hand written division is something too far for me to go into the past I could add more noise to the discussion than solution.

However, I can give you general pointers:

I see that in general you are on the good path. Your code is too expressive about the conditions, but this is also a natural way of working with “algos”. You “optimize” when you are sure that algo is written correctly. And with experience the starting code gets more optimized at typing time. And I do not mean “optimize” as “make it faster” but simply more compact/readable and that means with less points of failure.

For example: isNegative(String aNumber)

  • it can be one-liner:
    isNegative = aNumber.charAt(0) == ‘-’
  • it should not be called isNegative(…), better name would be setNegative(…)
  • the isNegative suggest that this will be a “getter” for the value but actually it is a “setter”

You use in some places BigInt.equals(), e.g: this.bigNum.equals(other.bigNum)

  • You need to write this method as default implementation does reference comparison of the fields. So actually even equal numbers will not be “equal” because the list behind bigNum will never be reference-equal to other list that stores exactly the same elements (digits) because it is simple different instance of a list.
  • your equals(other) method can be actually one-liner:
    return compareBigInts(this, other) == 0;

this.toString() == zero.toString()

  • should be replaced with: this.equals(zero)
  • in general never use == for comparing Strings, because Strings are just objects not real literals. You most likely will have two instances.
  • Even if the effect will be the same, the code is simply more readable than (this.toString().equals( zero.toString())