Reputation: 1593
I have a double and I have multiple checks in if statements to check in the value is passed in is between two values. eg
double d = 5.0;
if(d >= 0.0 && d < 5.0)
{
return 0;
}
if(d >= 5.0 && d < 10.0)
{
return 1;
}
if(d >= 10.0 && d < 15.0)
{
return 2;
}
I have about 15 of these if checks and it seems very inefficient and thought id ask if there was a more efficient way of computing the return value?
Upvotes: 1
Views: 3111
Reputation: 639
My Approach to reduce If condition
import java.util.LinkedHashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Double number = 6.0;//number to search
Map<Double, Double> numberRange = new LinkedHashMap<Double, Double>();
numberRange.put(0.0, 5.0);
numberRange.put(5.0, 10.0);
numberRange.put(10.0, 15.0);
// And So on
int status = getStatusOfNumberInRange(number, numberRange);
System.out.println(status);
}
private static int getStatusOfNumberInRange(Double number, Map<Double, Double> numberRange) {
int countStatus = 0;
for (Double minNum : numberRange.keySet()) {
if (checkNumberInRange(minNum, numberRange.get(minNum), number)) {
break;
}
countStatus++;
}
return countStatus;
}
private static boolean checkNumberInRange(Double minNum, Double maxNum, Double number) {
if (number >= minNum && number < maxNum) {
return true;
}
return false;
}
}
Upvotes: 0
Reputation: 351
It looks like you're implementing floor division by 5
. You can do that more concisely like this:
double d = 5.0;
return (int)d / 5;
Upvotes: 0
Reputation: 200138
If your bounds are completely arbitrary (unlike the example you have posted), then your idiom is almost as fast as you can get. You should just eliminate the redundant lower bound checks. First ensure that the result is positive and after that just test the upper bounds. If you use the ternary operator, and with proper formatting, you can get very concise and readable code:
if (d < 0) throw new IllegalArgumentException("Argument was negative");
if (d > UPPER_LIMIT) throw new IllegalArgumentException("Argument too large");
return d < THRESHOLD_0? 0
: d < THRESHOLD_1? 1
: d < THRESHOLD_2? 2
: d < THRESHOLD_3? 3
: 4;
If your bounds, however, are as regular as you have presented them in the example, and are not going to change, then it would of course pay off to exploit that regularity, for example
if (d < 0) throw new IllegalArgumentException("Argument was negative");
if (d > UPPER_LIMIT) throw new IllegalArgumentException("Argument too large");
return (int) (d / 5);
Upvotes: 3
Reputation: 98
Depending on the value of d, you may need to alter it before dividing. Otherwise, the int result will be truncated (not rounded). Something like:
double d = 4.99999;
System.out.println((long)(d / 5)); // Prints out '0'
d += 0.1;
System.out.println((long)(d / 5)); // Prints out '1'
Upvotes: 0
Reputation: 360562
The other answers have simpler solutions, e.g. the modulo business. But in general, if all of your conditions are sequential and non-overlapping, you don't need multiple distinct if() tests - you just need a single if/else/else/... chain:
if (d >= 0 && d < 5.0) {
return 0;
} else if (d < 10.0) {
return 1;
} else if (d < 15) {
return 2;
} else {
throw("out of range"); // or whatever should happen.
}
There's no point in continually testing the "lower" bound of d. With the if/else structure, the lower bound is already taken care of by the previous test.
Upvotes: 0
Reputation: 9403
Following should do the job:
return (int)(d / 5);
You might require a bound check for the lower limit (<0), so we can have a case as follows:
if (d > 0)
return (int)(d / 5);
throw new IllegalArgumentException("Argument was negative");
Upvotes: 0