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;
}
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
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
}
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).
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())