I had a homework to use functions in java to get the maximum number in a set of 3 numbers and this is what I came up with:
public static int max(int b, int a ,int d) {
int o =0;
while (b!=0 && a!=0 && d!=0)
{
b ;
a ;
d ;
o--;
}
return o;
}
The thing is if it is given 3 numbers it will work but I do not understand how it works.
CodePudding user response:
Ok, so what it's doing is increasing all three variables b
, a
, and d
, until any of them equals zero. It keeps a count o
of the number of times it's looped (i.e. the number of iterations necessary for any variable to hit zero), except negative.
If b
, a
, and d
are negative, then they would approach 0
relatively quickly, and o
would come out negative - but that's not what's happening is it? You're putting in positive numbers, and getting out a positive result.
That's because this solution relies on integer overflow. When b
, a
, or d
reaches the integer max value of 2147483647, it wraps back around to -2147483648, and keeps counting back up towards zero. Meanwhile, o
does the same thing in the opposite direction, wrapping the other direction. The math works out such that, when b
, a
, or d
reaches zero, then o
reaches the exact value that b
, a
, or d
started at.
(for negative numbers, the convergence happens much more quickly - but you might be in for a shock if you put both a negative and a positive number into this function. It'll tell you that the negative number is larger than the positive number!)
Now that you understand how it works, you also understand why this is a terrible solution to this problem. It will run for much, much longer than necessary in order to get a result (unless the input is negative, in which case it will only run for a little longer than necessary).
The more reasonable common-sense implementation would look like this:
public static int max(int b, int a ,int d) {
if (a >= b && a >= d) {
return a;
} else if (b >= a && b >= d) {
return b;
} else {
return d;
}
}
which incorpoates at most four operations, no matter how large a
, b
, or d
is.
CodePudding user response:
Assuming the b
, a
and d
integers are positive the while loop will run theoretically forever or realistically until you hit an error. Returning o
does nothing, it will just be a very small negative number which won't tell you anything about which of those three numbers is the larges, only how many iterations were there executed before the program failed.
It would be better to just add them to some array, order them and return the highest. You can even do it for N numbers, not just three.
private static int max(int... numbers){
return Collections.max(Arrays.asList(numbers));
}
Where Arrays.asList(numbers)
produces an List
from the input and Collections::max
will find the largest number in the list.
So you can call max(3, 4, 5, 6, 7, 8, 8, 9)
or max(1, 2)
Or if you need to do it without any any libraries, even though they ARE native, then just use a set of if
statements.
public static int max(int a, int b, int c) {
if (a >= b && a >= c) {
return a;
} else if (b >= a && b >= c) {
return b;
} else {
return c;
}
}
But this is much harder to read and understand than using the previous solution which clearly tells you what is going on without you having to consider a triple if
statement.
Also assuming from the fact that the input arguments are int b, int a ,int d
, spelling out
B A D
I'm willing to bet that this is not your answer, but actually an example of how NOT to do it which you should have fixed.